模板函数类型推导和运算符<<
Posted
技术标签:
【中文标题】模板函数类型推导和运算符<<【英文标题】:Template function type deduction and operator<< 【发布时间】:2013-02-05 20:29:19 【问题描述】:当我使用 MSVC++ 编译以下代码时,出现错误:
struct A
template<typename T>
void operator<<(T&& x)
;
void f()
int main()
A().operator<<( f ); // ok
A() << f; // error
return 0;
g++ 和 clang 都可以很好地编译这段代码。 AFAIK, 'ok' 和 'error' 行做同样的事情,类型 T 被推导出为 void(&) ()。还是允许 void() 和对函数的右值引用?如果是这样,它们的含义是什么? 像这样通过引用传递函数可以吗?编译 'error' 行是 MSVC++ 错误吗?顺便说一句,错误输出:
no operator found which takes a right-hand operand of type 'overloaded-function' (or there is no acceptable conversion)
could be 'void A::operator <<<void(void)>(T (__cdecl &&))'
with[ T=void (void) ]
【问题讨论】:
你能提供你的c++编译器的版本吗? MSVC++2012 与 NOV CTP 更新,gcc 4.5.3 和 4.7.2 测试,clang 3.0 和 3.1 测试。 我没有 VC11,所以我很难调查,但它闻起来像 URef 崩溃的错误。编译器错误地将其解释为 RRef 以运行并且不接受输入中的左值。检查typedef void (* test)(); test g() return f; ... A() << g();
是否有效会很有趣
函数指针确实有效,我已经检查过了,在执行 时使用 &f 而不是 f
好的,我提交了bug report
【参考方案1】:
为什么是void operator<<(T&& x)
? void operator<<(T& x)
达到目的。
函数可以用x()
在重载函数中调用,如下所示
struct A
template<typename T>
void operator<<(T& x)
x();
;
void f()
int main()
A().operator<<( f );
A() << f;
return 0;
【讨论】:
不,我使用右值引用,以便移动临时函数对象,而不是复制。对于 functions 任何一种方式都一样。【参考方案2】:所以,回答我自己的问题:
提供的代码是有效的,虽然允许对函数进行右值引用(它们的行为与左值引用相同),但在模板推导期间,T 应变为 void(&)()。
MSVC 中的bug 会阻止我的代码编译。
更新:该错误已在 Visual Studio 2013 编译器中修复
【讨论】:
以上是关于模板函数类型推导和运算符<<的主要内容,如果未能解决你的问题,请参考以下文章