像这样的返回类型在 c++11 中是否代表有意义的东西?
template <typename R>
R&& grabStuff();
T instance = grabStuff<T>();
如果没有移动构造函数,我希望grabStuff
应该抛出编译时错误,因为这似乎不允许返回类型使用复制构造函数R
像这样的返回类型在 c++11 中是否代表有意义的东西?
template <typename R>
R&& grabStuff();
T instance = grabStuff<T>();
如果没有移动构造函数,我希望grabStuff
应该抛出编译时错误,因为这似乎不允许返回类型使用复制构造函数R
与往常一样,在返回引用时,您必须返回对函数返回后仍然存在的东西的引用。你如何做到这一点取决于你。例子:
T global_thing;
T && get() { return std::move(global_thing); }
struct Foo { Foo(T &&); /* ... */ };
int main()
{
global_thing.reset();
Foo a(get());
global_thing.reset();
Foo b(get());
}
然而,返回右值引用的更典型的例子是std::move
它本身,它返回对你传递给它的东西的引用(因此调用者有责任提供有效的输入)。
如果函数的返回类型是一个右值引用,那么函数调用的结果就是一个xvalue;如果返回类型是非引用,则函数调用的结果是纯右值。
xvalue 和 prvalue 都是右值,它们之间存在一些细微差别,更像是参考和非参考之间的区别。例如,一个 xvalue 可能有一个不完整的类型,而一个纯右值通常应该有一个完整的类型或 void 类型。当 typeid 应用于类型为多态类类型的 xvalue 时,结果引用动态类型;对于纯右值,结果是指静态类型。
对于您的声明语句T instance = grabStuff<T>();
,如果 T 是类类型,我认为在这种情况下 xvalue 和 prvalue 没有区别。
初始值设定项是一个右值,因此编译器更喜欢移动构造函数。但是如果没有声明move构造函数,并且声明了一个带有const引用参数的拷贝构造函数,那么就会选择这个拷贝构造函数,并且不会出错。我不知道你为什么希望这是一个错误。如果这是一个错误,那么在从右值复制初始化某个对象时,任何旧代码都会不正确。
它可能是有意义的,这取决于你想用它做什么,以及你是如何实现这个功能的。
实际上,std::move
返回类型是T&&
(rvalue reference) 是有意义的,因为它定义了存在std::move
于 C++11 库中的目的: