摘要:为什么'='赋值运算符不能与两个相同类型std::unique_ptr<Expression, std::default_delete<Expression>>
的对象一起使用?
请注意,在代码中,类型被编写std::unique_ptr<Expression>
但在IntelliSense错误中扩展为前者。
IDE - 运行Visual C ++ 2010
操作系统 - Windows Vista
目标 - 控制台应用程序试图使用C ++ 11的实现
我已经在C ++中提供了一个表达式求值程序的例子,它显然符合新标准,因为应该是固体代码会给我错误而我猜它是因为VC ++不支持该功能。我得到的第一个错误是'make_unique'方法,VC ++说“标识符不存在”,所以我自己实现了
template<typename T>
std::unique_ptr<T> make_unique()
{
return std::unique_ptr<T>(new T());
} // Basically just wrapping 'new'? Not sure why
在网上找到了更好的一个,但它给出了错误,这^没有错误。我所做的就是删除... Args模板参数。我有一组表达式类,如下所示:
class Expression {
virtual ~Expression() {}
};
class BinaryExpression : public Expression {
public:
std::unique_ptr<Expression> lhs;
std::unique_ptr<Expression> rhs;
virtual char GetType() const = 0; // +,-,/,*
};
// Then MulExpression, DivExpression, PlusExpression, blah blah
现在我在这里得到错误,请注意,ParseAdditiveExpression()的返回类型是
// expr, lhs, and rhs are all of the same type
std::unique_ptr<Expression>:
auto rhs = ParseAdditiveExpression();
auto expr = make_unique<MulExpression>(); // Tried using: std::unique_ptr<Expression> expr;
expr->lhs = lhs; // Trouble Makers
expr->rhs = rhs; // All produce
lhs = expr; // The same errors
错误如下:
1 IntelliSense: "std::unique_ptr<_Ty, _Dx> &std::unique_ptr<_Ty, _Dx>::operator=(const std::unique_ptr<_Ty, _Dx> &) [with _Ty=Expression, _Dx=std::default_delete<Expression>]"
(declared at line 2352 of "C:\Program Files\Microsoft Visual Studio 10.0\VC\include\memory")
is inaccessible
c:\users\s_miller47\documents\visual studio 2010\projects\_vc++\powercalc\mathparser.h 133
现在,我认为这可能与'='正确大小的'const'有关,但我尝试将函数返回类型更改为适合,*或&amp;在返回类型之后,在我将其设置为expr-&gt; lhs之前尝试取消引用('*')值,甚至尝试过('&amp;')
因此,如果操作员无法访问,我该如何解决?我是否必须自己定义操作员? (废话)嗯,这是完整的代码:PasteBin Source Code Link
答案 0 :(得分:6)
std::unique_ptr
不可转让且不可复制。如果您想进行此类分配,则需要使用std::move()
:
lhs = std::move(expr);
答案 1 :(得分:5)
无法复制std::unique_ptr
的实例化;他们只能被移动(因此“独特”)。因此,对于赋值,您必须说要移动指针:
lhs = std::move(expr);
答案 2 :(得分:3)
问题是unique_ptr,顾名思义,维护一个唯一指针。这是autp_ptr被弃用的主要原因之一:它实际上将指针“移动”到了赋值中,而不是复制它。这被认为是一件坏事;如果你做“a = b”那么你希望有两个相当相同的对象“a”和“b”。你不希望“b”被清空。
因此,为了保持指针的唯一性,unique_ptr不允许任何形式的复制。