我最近安装了Visual Studio 2010 Professional RC来试用它并测试VC ++ 2010中实现的一些C ++ 0x功能。
我实例化std::vector
std::unique_ptr
,没有任何问题。但是,当我尝试通过将临时值传递给push_back
来填充它时,编译器会抱怨unique_ptr
的复制构造函数是私有的。我尝试通过移动它来插入一个左值,它工作得很好。
#include <utility>
#include <vector>
int main()
{
typedef std::unique_ptr<int> int_ptr;
int_ptr pi(new int(1));
std::vector<int_ptr> vec;
vec.push_back(std::move(pi)); // OK
vec.push_back(int_ptr(new int(2))); // compiler error
}
事实证明,问题既不是unique_ptr
也不是vector::push_back
,而是VC ++在处理rvalues时解决重载的方式,如下面的代码所示:
struct MoveOnly
{
MoveOnly() {}
MoveOnly(MoveOnly && other) {}
private:
MoveOnly(const MoveOnly & other);
};
void acceptRValue(MoveOnly && mo) {}
int main()
{
acceptRValue(MoveOnly()); // Compiler error
}
编译器抱怨无法访问复制构造函数。如果我将其公开,程序将编译(即使未定义复制构造函数)。
我是否误解了rvalue引用,或者它是VC ++ 2010实现此功能的一个(可能是已知的)错误?
答案 0 :(得分:12)
不幸的是,/ Za是错误的。它不应该执行elided-copy-constructor-accessibility检查(绑定rvalue引用不会调用复制构造函数,甚至理论上也是如此)。因此,不应使用/ Za。
Stephan T. Lavavej,Visual C ++库开发人员(stl@microsoft.com)
答案 1 :(得分:1)
首先,您需要关闭)
:
vec.push_back(int_ptr(new int(2))
的)强>; //编译错误
现在我没有第一个和第二个案例的编译器错误。
我使用Visual Studio 2010测试版。
答案 2 :(得分:1)
我注意到我禁用了语言扩展(\ Za)。启用扩展后,代码将被正确编译。我仍然认为这是一个错误,因为这里提供的代码是完全标准的(据我所知)并且不依赖于任何Microsoft扩展。