C++ boost::可选,不允许我重新分配常量值类型
在我看来,C++ boost::可选,不允许我重新分配常量值类型,c++,boost,assignment-operator,const-correctness,boost-optional,C++,Boost,Assignment Operator,Const Correctness,Boost Optional,在我看来,boost::optional 可选=>持有可变的Foo,可以在初始化后重新分配 optional const=>包含一个const Foo,初始化后无法重新分配 optional const=>(应该?)持有可变的Foo,但在初始化后无法重新分配 可选=>(应该?)持有常量Foo,可以在初始化后重新分配 前两个案例按预期工作。但是,可选常量取消对常量Foo的引用,可选常量不允许在初始化后重新分配(如中所述) 常量值类型的重新分配就是我遇到的,错误是: /usr/include/b
boost::optional
=>持有可变的Foo,可以在初始化后重新分配可选
=>包含一个const Foo,初始化后无法重新分配optional const
=>(应该?)持有可变的Foo,但在初始化后无法重新分配optional const
=>(应该?)持有常量Foo,可以在初始化后重新分配可选
可选常量
取消对常量Foo的引用,可选常量
不允许在初始化后重新分配(如中所述)
常量值类型的重新分配就是我遇到的,错误是:
/usr/include/boost/optional/optional.hpp:486:错误:将'const Foo'作为'Foo&Foo::operator=(const Foo&)'的'this'参数传递将丢弃限定符[-fppermissive]
发生在这里:
void assign_value(argument_type val,is_not_reference_tag) { get_impl() = val; }
构造之后,该实现对您参数化可选对象的类型使用赋值运算符。它显然不想要一个常量值的左操作数。但为什么不能将非常量可选值重置为新的常量值,例如在本例中:
optional<Foo const> theFoo (maybeGetFoo());
while (someCondition) {
// do some work involving calling some methods on theFoo
// ...but they should only be const ones
theFoo = maybeGetFoo();
}
可选theFoo(maybeGetFoo());
while(某些条件){
//做一些工作,包括在oo上调用一些方法
//…但它们应该是常量
theFoo=maybeGetFoo();
}
一些问题:
- 我想这在概念上是好的,而不能做到这一点只是实现中的一个侥幸,这是对的吗
- 如果我不编辑boost源代码,那么在不完全取消boost::optional的情况下,实现上述循环中的逻辑的干净方法是什么
- 如果这是有意义的,并且我要编辑boost::可选源代码(我已经做过了,尽管我怀疑他们很快会自己做),那么什么微创更改可能会起作用呢
因此,基本上问题似乎与for
optional&optional::operator=(T const&rhs)
中的注释有关:
注意:如果*已初始化,则使用T的赋值运算符,否则使用其复制构造函数
也就是说,假设您有boost::可选的theFoo代码>。由于默认构造的boost::optional
为空,因此语句:
theFoo=defaultFoo;
应该表示“将constructdefaultFoo
复制到theFoo
s的内部存储中。”由于该内部存储中没有任何内容,因此这是有意义的,即使该内部存储应该容纳const Foo
。完成后,foo
将不会为空
一旦foo
包含一个值,语句
theFoo=defaultFoo;
应该表示“将defaultFoo
分配到theFoo
s内部存储中的对象中。”但是theFoo
s内部存储是不可分配的(因为它是const
),因此这应该会引发(编译时?)错误
不幸的是,您会注意到最后两条语句是相同的,但在概念上需要不同的编译时行为。不过,没有什么可以让编译器分辨出两者之间的区别
特别是在您所描述的场景中,定义
boost::optional
的赋值运算符来代替语义可能更有意义:
如果*已初始化,则首先销毁其当前内容。然后使用T
的复制构造函数
毕竟,如果你真的想调用
T
的赋值运算符,完全可以通过说*theFoo=rhs
来回答你的三个问题:
Foo
类型,可以通过创建一个新的选项轻松地在可变和不可变选项之间切换。因此,在给定的情况下,您可以简单地将其作为可变的,然后将其复制到一个不可变的值中
optional<Foo> theMutableFoo (maybeGetFoo());
while (someCondition) {
optional<Foo const> theFoo (theMutableFoo);
// do some work involving calling some methods on theFoo
// ...but they should only be const ones
// ...therefore, just don't use theMutableFoo in here!
theMutableFoo = maybeGetFoo();
}
可选主题mutablefoo(maybeGetFoo());
while(某些条件){
可选的theFoo(主题为mutablefoo);
//做一些工作,包括在oo上调用一些方法
//…但它们应该是常量
//…因此,不要在这里使用mutablefoo!
theMutableFoo=maybeGetFoo();
}
考虑到它是一个类型的“精简代理”的模型,如果该类型没有封装在可选的。在这种情况下,普通常量值类型需要相同的处理
(3)一个人会