c++ - 为什么 std::move() 没有 _Remove_reference 就不能工作?

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

如您所知,_Remove_reference 的存在是为了将 T& 转换为 T 或将 T&& 转换为 T。

我怀着一种玩乐的心情写了下面的代码,它根本没有像我预期的那样工作,但不知道为什么。

template<class _Ty>
struct _Remove_reference
{   // remove reference
    typedef _Ty _Type;
    static void func(){ cout << "1" << endl; } 
};

// template<class _Ty>
// struct _Remove_reference<_Ty&>
// {    // remove reference
//  typedef _Ty _Type;
//  static void func(){ cout << "2" << endl; }
// };
// 
// template<class _Ty>
// struct _Remove_reference<_Ty&&>
// {    // remove rvalue reference
//  typedef _Ty _Type;
//  static void func(){ cout << "3" << endl; }
// };

template<class _Ty> inline
    typename _Remove_reference<_Ty>::_Type&&
    move(_Ty&& _Arg)
{   // forward _Arg as movable
    typename _Remove_reference<_Ty>::func();
    return ((typename _Remove_reference<_Ty>::_Type&&)_Arg);
}

int main(){
    int a1= 3;
    int&& a2 = move(a1); // can't convert the a1 to int&&
    return 0;
}

我想这都是关于引用折叠规则和模板参数推导,但我很困惑。必须打破我对此的好奇心才能睡个好觉。

提前致谢。

最佳答案

给定

template<class _Ty> inline
typename _Remove_reference<_Ty>::_Type&&
move(_Ty&& _Arg)

当你执行 move(a1) 时,_Ty 被推断为 int&。由于引用折叠规则,_Ty&& 仍将是 int&,因此您需要先删除引用以获取 int,然后才能将其设为右值引用。

这是模板参数推导规则的一个特例。如果你有一个函数参数是 T&& 其中 T 是一个模板参数,那么如果你传递一个左值(即命名对象或左值引用)给函数然后T 推导为 X&,其中 X 是左值对象的类型。如果您将右值(临时或右值引用)传递给函数,则 T 将被推导为 X

例如move(a1) 推导出 _Tyint&,而 move(42) 推导出 _Tyint

顺便说一句:我猜你从编译器的标准库中获取了这段代码 --- 用前导下划线和大写字母修饰的名称 _Like _This 是为编译器和标准库实现保留的。

关于c++ - 为什么 std::move() 没有 _Remove_reference 就不能工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8307238/

相关文章:

c++ - mingw32-make : *** No targets. 停止

C++:不同的语句范围与相同的语句范围

c++ - 如何将 ifstream 作为参数传递给 std::thread 函数?

c++ - 引用重载,而不是唯一的按值传递+ std::move?

c++ - void 和非 void 返回函数的完美转发

c++ - 没有 'rvalue references to *this' 功能的解决方法

c++ - 为可维护性和封装性构建 C++ 类层次结构

c++ - Qt tableView 在单元格中显示图像并在单击时获取路径

c++ - 可以将成员变量(CBrush *)分配给在具有新原因问题的类构造函数中动态分配的内存吗?

c++11 - 在 c++11 中使用文件和目录路径?