gpt4 book ai didi

c++ - boost::optional 不允许我重新分配 const 值类型

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:28:24 25 4
gpt4 key购买 nike

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

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

  • optional<Foo const> const => 持有一个 const Foo 并且不能在初始化后重新分配

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

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

前 2 个案例按预期工作。但是 optional<Foo> const取消对 const Foo 的引用,以及 optional<Foo const>不允许在初始化后重新分配(如 this question 中所述)。

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

/usr/include/boost/optional/optional.hpp:486: error: passing ‘const Foo’ as ‘this’ argument of ‘Foo& Foo::operator=(const Foo&)’ discards qualifiers [-fpermissive]

它发生在这里:

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();
}

一些问题:

  • 我是否认为想要这样做在概念上很好,而无法做到只是实现中的侥幸?

  • 如果我不编辑 boost 源,那么在不完全废弃 boost::optional 的情况下,有什么干净的方法可以像上面的循环那样实现逻辑?

  • 如果这确实有意义并且我要编辑 boost::optional 源(我已经必须这样做才能使它成为 support movable types ,尽管我怀疑他们很快就会自己这样做)那么哪些微创改变可能会奏效?

最佳答案

所以基本上问题似乎与 documentation 中的这条注释有关对于 optional& optional<T (not a ref)>::operator= ( T const& rhs ) :

Notes: If *this was initialized, T's assignment operator is used, otherwise, its copy-constructor is used.

也就是说,假设您有 boost::optional<const Foo> theFoo; .由于默认构造boost::optional<>为空,语句:

theFoo=defaultFoo;

应该表示“将构造 defaultFoo 复制到 theFoo 的内部存储中。”由于该内部存储中已经没有任何内容,所以这是有道理的,即使内部存储应该容纳一个 const Foo。 .完成后,theFoo不会为空。

一次theFoo包含一个值,语句

theFoo=defaultFoo;

应该表示“将 defaultFoo 分配给 theFoo 的内部存储中的对象。”但是theFoo s 内部存储不可分配(因为它是 const ),因此这应该引发(编译时?)错误。

不幸的是,您会注意到最后两个语句是相同的,但在概念上需要不同的编译时行为。不过,编译器无法分辨两者之间的区别。


特别是在您描述的场景中,定义 boost::optional<...> 可能更有意义的赋值运算符改为具有语义:

If *this was initialized, its current contents are first destroyed. Then T's copy-constructor is used.

毕竟,调用 T 是完全可能的的赋值运算符,如果这是你真正想做的,说 *theFoo = rhs .

关于c++ - boost::optional 不允许我重新分配 const 值类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11459270/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com