C++右值引用和引用折叠

当我们将一个左值传递给右值引用参数时,且此右值引用指向模板类型参数(T&&)时,编译器推断模板类型参数为左值引用类型而非左值。

当我们间接创建一个引用的引用,如类型别名或模板参数,则这些引用形成了折叠:

  • T& &,T& &&,T&& &折叠为T&
  • T&& &&折叠为T&&

因为有上述两个规则,所以如果一个函数参数是指向模板参数类型的右值引用,则可以传递给它任意类型的实参。如果将一个左值传递给这样的参数,则函数参数被实例化为了一个普通的左值引用。

template <typename T>
void print1(T&& value)
{
    cout << value << endl;
}

void print2(int&& value)
{
    cout << value << endl;
}

int main()
{
    int value = 2;
    print1(value);//正确
    print2(value);//无法将参数 1 从“int”转换为“int && ”
    system("pause");
}

std::move可以获得一个绑定到左值上的右值引用,它除了利用右值引用和引用折叠外,还利用了一个规则:虽然不能隐式地将一个左值转换为右值引用,但是我们可以用static_cast显式地将一个左值转换为一个右值引用。

template <class _Ty>
_NODISCARD constexpr remove_reference_t<_Ty>&& move(_Ty&& _Arg) noexcept { // forward _Arg as movable
    return static_cast<remove_reference_t<_Ty>&&>(_Arg);
}

转载于:https://www.jianshu.com/p/6741f9d68fdf

猜你喜欢

转载自blog.csdn.net/weixin_33947521/article/details/91064941
今日推荐