9

像这样的返回类型在 c++11 中是否代表有意义的东西?

template <typename R>
R&& grabStuff();

T instance = grabStuff<T>();

如果没有移动构造函数,我希望grabStuff应该抛出编译时错误,因为这似乎不允许返回类型使用复制构造函数R

4

3 回答 3

7

与往常一样,在返回引用时,您必须返回对函数返回后仍然存在的东西的引用。你如何做到这一点取决于你。例子:

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它本身,它返回对你传递它的东西的引用(因此调用者有责任提供有效的输入)。

于 2012-04-14T16:20:00.127 回答
2

如果函数的返回类型是一个右值引用,那么函数调用的结果就是一个xvalue;如果返回类型是非引用,则函数调用的结果是纯右值。

xvalue 和 prvalue 都是右值,它们之间存在一些细微差别,更像是参考和非参考之间的区别。例如,一个 xvalue 可能有一个不完整的类型,而一个纯右值通常应该有一个完整的类型或 void 类型。当 typeid 应用于类型为多态类类型的 xvalue 时,结果引用动态类型;对于纯右值,结果是指静态类型。

对于您的声明语句T instance = grabStuff<T>();,如果 T 是类类型,我认为在这种情况下 xvalue 和 prvalue 没有区别。

初始值设定项是一个右值,因此编译器更喜欢移动构造函数。但是如果没有声明move构造函数,并且声明了一个带有const引用参数的拷贝构造函数,那么就会选择这个拷贝构造函数,并且不会出错。我不知道你为什么希望这是一个错误。如果这是一个错误,那么在从右值复制初始化某个对象时,任何旧代码都会不正确。

于 2012-04-15T02:53:39.693 回答
1

它可能是有意义的,这取决于你想用它做什么,以及你是如何实现这个功能的。

实际上,std::move返回类型是T&&(rvalue reference) 是有意义的,因为它定义了存在std::move于 C++11 库中的目的:

于 2012-04-14T16:01:41.523 回答