Visual C ++ 2010,右值引用错误? [英] Visual C++ 2010, rvalue reference bug?

查看:85
本文介绍了Visual C ++ 2010,右值引用错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it a bug in Visual C++ 2010 or right behaviour?

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& amp;调用它。输出:

I thought, the function f(T &&) should never be called but it's called with T = int &. The output:


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

更新1 您是否知道任何C ++ x0编译器作为参考?我已经尝试过comeau在线试驾,但无法编译r值参考。

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.

更新2 解决方法(使用SFINAE):

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上触发(否,否),即使没有功能模板实例化也是如此。解决方法(由于@Johannes Schaub-litb)

Update 3 Some of compilers trigger on static_assert(false, "no way") even if no function template instantiation. Workaround (thanks to @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");


推荐答案

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

As I understand it (and I may not be completely right; the specification is a bit complicated), the template type deduction rules conspire against you.

编译器首先尝试替换所有模板(此时尚未选择&mdash ;只需寻找选项)并获取:

The compiler first attempts to substitute all templates (it's not choosing at this point yet—just looking for options) and gets:


  • T const& r int 左值与 T = int 匹配,创建 f(int const&)

  • T& r int 左值与 T = int& int& && 减少为 int& ,创建 f(int&) 规范)。

  • T const &r matches int lvalue with T = int, creating f(int const &)
  • T &&r matches int lvalue with T = int& and int & && reduces to int&, creating f(int &) (there are rules saying this in the spec).

现在是选择正确的重载,而后者则更好,因为第一个简历资格方面有所不同,后者则没有。这也是为什么删除 const 时会出现模棱两可的过载错误的原因-过载最终变得完全相同。

Now it comes to selecting correct overload and the later is better match, because the first differs in cv-qualification and the later does not. That's also the reason why when you remove the const, you get ambiguous overload error—the overloads end up being exactly the same.

广告 Update1 gcc 支持许多C ++ 0x功能。您可以从 mingw 中获取本机Windows版本,也可以使用 cygwin

Ad Update1: gcc supports many of the C++0x features. You can get native windows build from mingw or use cygwin.

Ad Update2 :如果您确实需要分别为rvalue和lvalue重载,那似乎是唯一的选择。但是大多数模板都可以通过任何形式的引用来做正确的事情,也许使用 std :: forward 来确保所调用函数的正确解析(取决于它们是否获得右值或左值)

Ad Update2: If you really need separate overloads for rvalue and lvalue, that seems to be the only option. But most templates do the right thing with just any kind of reference, perhaps using std::forward to ensure proper resolution of functions they call depending on whether they got rvalue or lvalue).

这篇关于Visual C ++ 2010,右值引用错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆