c++ - Visual C++ 2010,右值引用错误?

标签 c++ visual-c++ c++11 visual-c++-2010 rvalue-reference

这是 Visual C++ 2010 中的错误还是正确的行为?

template<class T>
T f(T const &r)
{
    return r;
}

template<class T>
T f(T &&r)
{
    static_assert(false, "no way"); //< line # 10
    return r;
}

int main()
{
    int y = 4;
    f(y); //< line # 17
}

我想,函数 f(T &&) 永远不应该被调用,但它是用 T = int & 调用的。输出:

    main.cpp(10): error C2338: no way
          main.cpp(17) : see reference to function template instantiation 'T f(T)' being compiled
          with
          [
              T=int &
          ]

Update 1 Do you know any C++x0 compiler as a reference? I've tried comeau online test-drive but could not compile r-value reference.

Update 2 Workaround (using SFINAE):

#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_reference.hpp>

template<class T>
T f(T &r)
{
    return r;
}

template<class T>
typename ::boost::disable_if< ::boost::is_reference<T>, T>::type f(T &&r)
{
    static_assert(false, "no way");
    return r;
}

int main()
{
    int y = 4;
    f(y);
    // f(5); // generates "no way" error, as expected.
}

更新 3 即使没有函数模板实例化,一些编译器也会触发 static_assert(false, "no way")。解决方法(感谢@Johannes Schaub - litb)

template<class T> struct false_ { static bool const value = false; };
...
static_assert(false_<T>::value, "no way");

static_assert(sizeof(T) == sizeof(T), "no way");

最佳答案

据我了解(我可能不完全正确;规范有点复杂),模板类型推导规则合谋对你不利。

编译器首先尝试替换所有模板(此时它还没有选择——只是寻找选项)并得到:

  • T const &rint 左值与 T = int 匹配,创建 f (int const &)
  • T &&rint 左值与 T = int&int & && 匹配> 减少到 int&,创建 f(int &)(在 spec 中有规定)。

现在要选择正确的过载,后者更匹配,因为前者在 cv 限定上不同而后者没有。这也是为什么在删除 const 时会出现不明确的重载错误的原因——重载最终完全相同。

广告更新1:gcc支持many of the C++0x features .您可以从 mingw 获取 native Windows 构建或使用 cygwin .

Ad Update2:如果您真的需要右值和左值的单独重载,那似乎是唯一的选择。但是大多数模板只要使用任何类型的引用就可以做正确的事情,也许使用 std::forward 来确保正确解析它们调用的函数,具体取决于它们是右值还是左值)。

关于c++ - Visual C++ 2010,右值引用错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5038305/

相关文章:

c++ - 为什么这个循环中的 lambda 函数没有按值捕获参数?

c++ - 如何将此 VC++ 6 代码转换为 VC++ 2008?

c++ - 在 block 作用域中使用 extern

c++ - 容器的 3D 网格:嵌套 std::vector 与 std::unordered_map

c++ - 为什么对变量的引用有时表现为大小为 1 的数组?

c++ - QLocalServer 不会启动传入连接

c++ - 精神规则中定义功能发出警告

c++ - 在继承自抽象类的模板类中正确使用未定义类型

c++ - 将 C++11 std::thread 移植到 boost::thread 编译问题

C++ intel TBB 内循环优化