Does a return type like this represent something meaningful in c++11?
这样的返回类型是否表示c++11中的一些有意义的东西?
template <typename R>
R&& grabStuff();
T instance = grabStuff<T>();
I would hope that grabStuff
should throw a compile-time error if R
does not have a move constructor, since this would seem to disallow the return type to use a copy constructor
如果R没有move构造函数,我希望grabStuff应该抛出编译时错误,因为这似乎不允许返回类型使用复制构造函数
3 个解决方案
#1
5
As always, when returning references you must return a reference to something that's still alive after the function returns. How you do that is up to you. Example:
与往常一样,当返回引用时,您必须返回一个引用,该引用在函数返回后仍然存在。如何做到这一点取决于你自己。例子:
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());
}
The more typical example for returning an rvalue reference is std::move
itself, though, which returns a reference to the thing you pass into it (and thus it's the caller's responsibility to provide a valid input).
返回一个rvalue引用的更典型的例子是std::move本身,它返回一个对您传入它的东西的引用(因此调用者有责任提供一个有效的输入)。
#2
1
It may be meaningful depending on what you want to do with it, and how you've implemented the function.
它可能有意义,这取决于您想要对它做什么,以及您如何实现这个函数。
In fact, std::move
return type is T&&
(rvalue reference) which is meaningful, as it defines the very purpose of the existence of std::move
in the C++11 library:
实际上,std::move return类型是T&& (rvalue reference),这是有意义的,因为它定义了std:::在c++ 11库中移动的目的:
- std::move
- std::移动
#3
1
If the return type of a function is an rvalue reference, then the result of the function call is an xvalue; if the return type is non-reference, then the result of the function call is a prvalue.
如果函数的返回类型是一个rvalue引用,那么函数调用的结果就是一个xvalue;如果返回类型是非引用的,那么函数调用的结果就是一个prvalue。
Both xvalue and prvalue are rvalues, there are some minor differences between them, more like differences between reference and non-reference. For example, an xvalue may have an incomplete type, while a prvalue shall usually have a complete type or the void type. When typeid is applied to an xvalue whose type is a polymorphic class type, the result refers to the dynamic type; and for prvalue, the result refers to the static type.
xvalue和prvalue都是rvalues,它们之间有一些细微的差异,更像是reference和non-reference之间的差异。例如,xvalue可能有一个不完整的类型,而prvalue通常有一个完整的类型或void类型。当将typeid应用于类型为多态类类型的xvalue时,结果引用动态类型;对于prvalue,结果引用静态类型。
For your declaration statement T instance = grabStuff<T>();
, if T is a class type, I think there is no difference between xvalue and prvalue in this context.
对于您的声明语句T instance = grabStuff
The initializer is an rvalue, so the compiler prefers a move constructor. But if no move constructor is declared, and a copy constructor with const reference parameter is declared, then this copy constructor will be chosen, and there is no error. I don't know why do you want this to be an error. If this is an error, any old code will be incorrect when copy-initialize some object from an rvalue.
初始化器是一个rvalue,所以编译器更喜欢一个move构造函数。但是如果没有声明move构造函数,并且声明了带有const引用参数的复制构造函数,那么将选择这个复制构造函数,并且没有错误。我不知道你为什么要把它当成一个错误。如果这是一个错误,那么当从rvalue复制初始化某个对象时,任何旧代码都将是不正确的。
#1
5
As always, when returning references you must return a reference to something that's still alive after the function returns. How you do that is up to you. Example:
与往常一样,当返回引用时,您必须返回一个引用,该引用在函数返回后仍然存在。如何做到这一点取决于你自己。例子:
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());
}
The more typical example for returning an rvalue reference is std::move
itself, though, which returns a reference to the thing you pass into it (and thus it's the caller's responsibility to provide a valid input).
返回一个rvalue引用的更典型的例子是std::move本身,它返回一个对您传入它的东西的引用(因此调用者有责任提供一个有效的输入)。
#2
1
It may be meaningful depending on what you want to do with it, and how you've implemented the function.
它可能有意义,这取决于您想要对它做什么,以及您如何实现这个函数。
In fact, std::move
return type is T&&
(rvalue reference) which is meaningful, as it defines the very purpose of the existence of std::move
in the C++11 library:
实际上,std::move return类型是T&& (rvalue reference),这是有意义的,因为它定义了std:::在c++ 11库中移动的目的:
- std::move
- std::移动
#3
1
If the return type of a function is an rvalue reference, then the result of the function call is an xvalue; if the return type is non-reference, then the result of the function call is a prvalue.
如果函数的返回类型是一个rvalue引用,那么函数调用的结果就是一个xvalue;如果返回类型是非引用的,那么函数调用的结果就是一个prvalue。
Both xvalue and prvalue are rvalues, there are some minor differences between them, more like differences between reference and non-reference. For example, an xvalue may have an incomplete type, while a prvalue shall usually have a complete type or the void type. When typeid is applied to an xvalue whose type is a polymorphic class type, the result refers to the dynamic type; and for prvalue, the result refers to the static type.
xvalue和prvalue都是rvalues,它们之间有一些细微的差异,更像是reference和non-reference之间的差异。例如,xvalue可能有一个不完整的类型,而prvalue通常有一个完整的类型或void类型。当将typeid应用于类型为多态类类型的xvalue时,结果引用动态类型;对于prvalue,结果引用静态类型。
For your declaration statement T instance = grabStuff<T>();
, if T is a class type, I think there is no difference between xvalue and prvalue in this context.
对于您的声明语句T instance = grabStuff
The initializer is an rvalue, so the compiler prefers a move constructor. But if no move constructor is declared, and a copy constructor with const reference parameter is declared, then this copy constructor will be chosen, and there is no error. I don't know why do you want this to be an error. If this is an error, any old code will be incorrect when copy-initialize some object from an rvalue.
初始化器是一个rvalue,所以编译器更喜欢一个move构造函数。但是如果没有声明move构造函数,并且声明了带有const引用参数的复制构造函数,那么将选择这个复制构造函数,并且没有错误。我不知道你为什么要把它当成一个错误。如果这是一个错误,那么当从rvalue复制初始化某个对象时,任何旧代码都将是不正确的。