boost :: optional不让我重新分配const值类型

Hos*_*ork 6 c++ boost const-correctness assignment-operator boost-optional

在我看来应该有四种变体 boost::optional

  • optional<Foo> =>持有一个可变的Foo,可以在初始化后重新分配

  • optional<Foo const> const =>持有一个const Foo,初始化后无法重新分配

  • optional<Foo> const =>(应该?)保持一个可变的Foo,但在初始化后不能重新分配

  • optional<Foo const> =>(应该?)持有一个const Foo,可以在初始化后重新分配

前2个案例按预期工作.但是对optional<Foo> constconst Foo 的解引用,并且optional<Foo const>在初始化之后不允许重新分配(如本问题所述).

const值类型的重新分配是我遇到的具体内容,错误是:

/usr/include/boost/optional/optional.hpp:486:错误:使 'const的富' 为 '这个' 的参数 '富&富::运算符=(const的富&)' 丢弃限定符[-fpermissive]

它发生在这里:

void assign_value(argument_type val,is_not_reference_tag) { get_impl() = val; }
Run Code Online (Sandbox Code Playgroud)

构造之后,实现使用赋值运算符作为参数化可选的类型.它显然不希望左手操作数是一个const值.但是为什么不能将非const可选项重置为新的const值,例如在这种情况下:

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();
}
Run Code Online (Sandbox Code Playgroud)

一些问题:

  • 我是否正确,希望这在概念上很好,而且无法做到这只是实施中的侥幸?

  • 如果我不编辑boost源,那么在上面的循环中实现逻辑的干净方法是什么,而不是完全废弃boost :: optional?

  • 如果这确实有意义并且我要编辑boost :: optional源(我已经不得不做它以支持可移动类型,虽然我怀疑他们将很快自己这样做)然后什么微创改变可能做诀窍?

Hos*_*ork 2

(1)人们对行为“应该”是什么的看法取决于可选值是“零个或一个任意类型的对象的容器”还是“具有附加功能的类型的瘦代理”。现有代码使用后一种想法,通过这样做,它删除了列表中“四种不同行为”的一半。这降低了复杂性,并防止您无意中引入低效的用法。

(2)对于任何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();
}
Run Code Online (Sandbox Code Playgroud)

考虑到它是类型的“瘦代理”的模型,如果类型没有包装在可选中,这与您必须做的事情完全相同。在这种情况下,普通的常量值类型需要相同的处理。

(3) 必须跟进@Andrzej 提供的信息才能找到答案。但是这样的实现更改可能不会比每次创建一个新的可选值(如上面的循环中)更好。最好接受现有的设计。


资料来源:@R.MartinhoFernandez@KerrekSB