【问题标题】: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

标签: c++ c++11 visual-c++ reference template-argument-deduction


【解决方案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 编译器中修复

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-15
    • 2015-03-12
    • 2021-06-22
    • 1970-01-01
    相关资源
    最近更新 更多