templates之为什么在 C++0x 中,编译器选择通用移动赋值而不是特定移动赋值
我有以下代码:
#include <iostream>
using namespace std;
template <class T> class Foo {
public:
template <class U> void operator = (const U &u) {
cout << "generic copy assigment\n";
}
void operator = (const Foo<T> &f) {
cout << "specific copy assigment\n";
}
template <class U> void operator = (U &&u) {
cout << "generic move assigment\n";
}
void operator = (Foo<T> &&f) {
cout << "specific move assigment\n";
}
};
int main() {
Foo<int> i, j;
i = j;
return 0;
}
如果运行,它会打印“通用移动分配”,即编译器更喜欢移动而不是副本。但是,如果我注释掉两个移动分配:
template <class T> class Foo {
public:
template <class U> void operator = (const U &u) {
cout << "generic copy assigment\n";
}
void operator = (const Foo<T> &f) {
cout << "specific copy assigment\n";
}
};
输出是“特定的复制赋值”。
换句话说,当类别启用移动时,将选择通用移动而不是特定移动,而如果类别不启用移动,则选择特定副本而不是通用移动。
这是 Visual Studio 2010 的错误还是 c++0x 规范中定义了这种行为?
请您参考如下方法:
您的模板不是“通用移动分配”。但它是一个“完美的转发器”,除了在你的情况下它不转发。 C++0x 中的规则是模板参数推导特别对待参数“T&&”:左值参数将 T
推导为 ArgType&
,而右值参数将其推导为 参数类型
。这样,ArgType
类型的左值将屈服于最终参数类型 ArgType&
,而右值最终将屈服于 ArgType&&
。
在您的例子中,右手边的左值产生一个推导的参数类型“Foo &”,它与左值参数完全匹配。
不过,目前的草案 (n3126) 禁止编译器使用模板来执行复制赋值(在一个措辞非常困惑的段落中)。取决于issue 1080的分辨率这是否会改变。
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。