模板函数类型推导和运算符<<

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() &lt;&lt; g(); 是否有效会很有趣 函数指针确实有效,我已经检查过了,在执行 时使用 &f 而不是 f 好的,我提交了bug report 【参考方案1】:

为什么是void operator&lt;&lt;(T&amp;&amp; x)void operator&lt;&lt;(T&amp; 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 编译器中修复

【讨论】:

以上是关于模板函数类型推导和运算符<<的主要内容,如果未能解决你的问题,请参考以下文章

c++ stl函数模板类型推导

C++中类与函数的模板类型推导?

initializer_list 和模板类型推导

带有类型推导的 swig python 模板函数

推导返回类型模板 C++

1.2 模板参数推导