我正在阅读Scott Meyers的《 Effective Modern C ++》一书,其中作者提到了
“
for i in range(0,len(data.index)): ... ... if data.at[i,'BestP_A'] == 'Bra': polemin = [data.loc[i,'Bra'],data.loc[i,'Nah'],data.loc[i,'Tec'],data.loc[i,'Ryc'],data.loc[i,'Hla']] data.at[i,'BestP_Min'] = min(polemin) data.at[i,'BestP_Idx'] = polemin.index(min(polemin)) elif data.at[i,'BestP_A'] == 'Obr': polemin = [data.loc[i,'Obr'],data.loc[i,'Nah']...
的副本通常是移动构建的,而rvalues
通常是副本构建的。”
所以我想通过编写一个lvalues
类来测试它,该类将临时构造到一个Test
函数中,该函数将右值引用作为dummy
类的参数。 / p>
我希望看到上述报价的输出,如:
Test
但是我只有:
Constructed...
Moving...
Hello world
为什么移动构造函数未调用?是否像Constructed...
Hello world
一样将临时传递给dummy
有任何未定义的行为?我正在使用C ++ 17。
代码如下:
dummy(Test{});
答案 0 :(得分:1)
出于相同的原因,以下代码不会调用复制构造函数:
guard compareArray2.count == createDateArray.count else { return false}
for i in 0..<compareArray2.count {
if df.string(from: compareArray2[i]) != df.string(from: createDateArray[i]) {
return false
}
}
return true
...因为该对象是通过引用传递的。在上面的代码中,它是一个左值引用,而在您给出的示例中是一个右值引用,但仍然是一个引用。
如果要按值传递它,则需要在函数参数类型中反映出来:
class Test {
...
};
void dummy(Test& t) { // passed as an lvalue reference
test.print();
}
int main() {
Test t;
dummy(t);
return 0;
}
然后需要调用构造函数以按值传递void dummy(Test t) {
...
}
,除非发生复制省略,请参见下面的补充内容。
请注意,t
实际上不会移动任何东西。它将输入转换为右值引用并返回。
尽管有一些细微差别。 C ++ 17保证不会为prvalue分配创建临时目录,即std::move
在这种情况下不会调用copy或move构造函数,因为省去了创建临时目录。尽管该语言没有要求,但在C ++ 17之前的版本中仍可能会发生复制省略。因此,如果您想观察通过将prvalue dummy(Test{})
按值传递给-fno-elide-constructors
函数(如上例所示)时调用move构造函数,请确保设置Test{}
编译器标志。>
答案 1 :(得分:-1)
基本上,仅构造一个Test实例:dummy(Test{})
,但此举表示如果要从一个实例移到另一个实例,则至少存在两个实例。