非常量引用只能用左值初始化吗?

按说非常量左值引用是不能使用右值初始化的

struct S
{
    S& operator=(S&&) = delete;
    S(S&&) = delete;
    S(){}
};

S s;
S& rs = std::move(s);

但是为什么上面代码可以编译通过呢? 这不是将非常量左值引用绑定右值吗?
比如下面的赋值操作就会报错

int& ri = 1;`

之后又尝试了如下代码

struct S
{
    S& operator=(S&&) = delete;
    S(S&&) = delete;
    S(){}
};

void test(S&)
{

}

int main()
{
    test(std::forward<S>(S()));
    return 0;
}

这里调用test的实参也是右值,但是也编译通过。

还有这样

void test(S&)
{

}

template<typename T>
void func(T&& t)
{
    test(std::forward<T>(t));
}

int main()
{
    func(S());
    return 0;
}

这里func的推导类型为func<S>(S&&), 按说完美转发之后调用test(S&&), 而上面只提供了test(S&),但是编译也没问题。
这都是怎么回事呀

阅读 1.6k
1 个回答

c++ 引用绑定的规则其实挺复杂的。

cppreference:reference initialization

标准:dcl.init.ref

你的所有测试 gcc 都编译不过。你用有什么编译器,什么版本,什么编译选项?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进