C++11中如何为void类型特化类的operator<<=二元运算符重载?
问题:适配返回void场景的二元运算符重载特化
我需要实现一套记录函数返回值的宏/模板封装,核心是通过DebugPlacement类的operator<<=模板重载打印返回值并返回原结果。当前实现对非void返回值正常工作,但遇到返回void的函数时失效。
现有实现
宏定义:
#define Return return DebugPlacement({__FILE__,__LINE__}) <<=
DebugPlacement类:
struct DebugPlacement { const char* path; int line; template <class Arg> const Arg& operator <<= (const Arg& arg)const { std::cerr << "DIAG: " << path << ":" << line << " returns " << arg << std::endl; return arg; } };
问题场景
当返回void类型时,如下代码会编译报错:
extern void MyVFunction(int arg1, int arg2); void MyVFunctionStub(int arg1, int arg2) { Return MyVFunction(arg1, arg2); }
错误信息:
error: no viable overloaded '<<=' note: candidate template ignored: substitution failure [with T = void]: cannot form a reference to 'void'
尝试过的无效方案
- 尝试特化void引用参数:
template <> auto DebugPlacement::operator <<=(void& t)const -> void& // 错误:无法形成void类型的引用
- 尝试直接接受void参数:
void operator <<=(void t)const // 错误:参数不能为void类型
当前使用C++11环境,需找到可行方案适配void返回值场景。
解决方案
C++中无法直接定义接受void类型参数的函数/运算符,但可以通过宏内类型推导+分支处理绕开限制,无需修改原运算符的核心逻辑:
步骤1:扩展DebugPlacement类
添加专门处理void场景的日志函数:
#include <type_traits> // 需包含此头文件 struct DebugPlacement { const char* path; int line; template <class Arg> const Arg& operator <<= (const Arg& arg)const { std::cerr << "DIAG: " << path << ":" << line << " returns " << arg << std::endl; return arg; } // 新增:处理void返回的日志函数 void log_void() const { std::cerr << "DIAG: " << path << ":" << line << " returns void" << std::endl; } };
步骤2:修改宏定义
利用C++11的decltype和std::is_void做类型判断,分支处理void和非void返回:
#define Return do { \ DebugPlacement dp{__FILE__, __LINE__}; \ /* 用lambda包装表达式,推导其返回类型 */ \ auto exec_expr = [&]() -> decltype(auto) { return __VA_ARGS__; }; \ typedef decltype(exec_expr()) return_type; \ \ if (std::is_void<return_type>::value) { \ exec_expr(); /* 先执行void表达式 */ \ dp.log_void(); /* 打印void返回日志 */ \ return; \ } else { \ return dp <<= exec_expr(); /* 非void场景走原逻辑 */ \ } \ } while(0)
效果验证
对于void返回的函数调用,宏会先执行函数,再打印returns void的日志;对于非void返回值,仍保留原有的打印并返回逻辑,完全兼容原有使用方式。
内容的提问来源于stack exchange,提问作者Gem Taylor
相关产品推荐
相关产品推荐

