让我们采取两个结构/类
struct C1{
C1(){};
C1(C1&){std::cout<<"copy"<<std::endl;}
C1(C1&&){std::cout<<"move"<<std::endl;}};
struct C2{
C1 c;
C2(){};
C1 get1(){return c;}
C1 get2(){return std::move(c);}};
Run Code Online (Sandbox Code Playgroud)
然后
C1 a1=C2().c;
C1 a2=C2().get1();
C1 a3=C2().get2();
Run Code Online (Sandbox Code Playgroud)
输出是
move
copy
move
Run Code Online (Sandbox Code Playgroud)
我们知道rvalues的成员本身就是rvalues.这就是为什么使用a1,调用移动构造函数.为什么,在a2的情况下调用复制构造函数.我们从函数返回一个rvalue.
换句话说,std :: move强制转换为右值.但是,作为一个rvalue的成员,c,已经是一个rvalue.为什么a2和a3的行为之间存在差异?
使用Efficient Modern C++,第25项.我们有一个例子
class Widget {
public:
template<typename T>
void setName(T&& newName)
{ name = std::forward<T>(newName); }
...
};
Run Code Online (Sandbox Code Playgroud)
class Widget {
public:
void setName(const std::string& newName)
{ name = newName; }
void setName(std::string&& newName)
{ name = std::move(newName); }
...
};
Run Code Online (Sandbox Code Playgroud)
Widget w;
w.setName("Adela Novak");
Run Code Online (Sandbox Code Playgroud)
现在假设情况1,该书指出文字被传递给w的名称数据成员中的t std :: string的赋值运算符.
假设情况2,本书指出 - >首先从文字创建临时,调用字符串构造函数,因此setName参数可以绑定到它,并且将此临时文件移动到w的名称数据成员中.
为什么这种行为上的差异会产生,我该怎么想呢?
也就是说,为什么在案例1中不需要临时的?为什么会有区别?T &&是否被推断为对字符串的右值引用,因此得出与案例2相同的行为(显然不是,根据本书,但为什么)?
我有一个构造函数
T(someClass<double> o);
Run Code Online (Sandbox Code Playgroud)
该类someClass初始化为double* x.那是
someClass<double>(double * X);
Run Code Online (Sandbox Code Playgroud)
为什么以下工作?
double * X=new X[10];
T obj(X);
Run Code Online (Sandbox Code Playgroud)
为什么这个工作,即使没有构造函数T,double *作为参数(它应该得到一个实例someClass)?编译器是否隐式初始化someClass double*?