const std :: optional的内容是否总是const?

时间:2019-03-08 09:28:20

标签: c++ c++17

我认为

std::optional<const std::string>

允许为可选字段分配新值,但是无法更改字符串本身和输入值

const std::optional<const std::string>

不可能同时做。但是接下来呢?

const std::optional<std::string>

2 个答案:

答案 0 :(得分:1)

然后让我们做一些测试:

#include <string>
#include <optional>

int main() {
    using n_c = std::optional<const std::string>;
    using c_n = const std::optional<std::string>;
    using n_n = std::optional<std::string>;

    n_c opt_n_c{"a"};
    c_n opt_c_n{"a"};
    n_n opt_n_n{"a"};

    opt_n_c.emplace("b");
    // opt_c_n.emplace("b");
    opt_n_n.emplace("b");

    // opt_n_c->pop_back();
    // opt_c_n->pop_back();
    opt_n_n->pop_back();
}

注释掉的行不起作用。

这样想:非常数std::optional<T>可以没有值或T可以被替换(不使用T::operator=,而只是破坏当前持有的{{ 1}}(如果存在)并构建一个新的)。尽管T可能没有std::optional<const T>,但非常量const T可以做的完全一样,因此您不能更改保留的值,但是仍然可以更改什么值举行。 operator=也是“逻辑常量”。如果const std::optional<T>等于另一个const std::optional<T>,并且没有触及任何非const引用,则它们(应)始终保持相等,因此保持值(应)不变。这就是为什么它们将const引用返回到保持值的原因,也是const std::optional<T>const std::optional<T>实际上是相同的原因。

答案 1 :(得分:1)

  

那下面呢?

const std::optional<std::string>

标准库中的所有内容都将是const正确的-因此,optional上的访问器都已被const限定为适当的资格。在const optional<T>上调用value()operator*()会给您const T&(或const T&&),而不是T&

您无权直接访问可修改的参考。

请注意,另一方面,如果您有一个const optional<int*>,则指针本身就是const,而不是指针。这样就可以了:

int i = 42;
const std::optional<int*> opt(&i);
*opt.value() = 57;
assert(i == 57);

  

const std::optional的内容是否总是const

从技术上来说,以上内容实际上并未回答您的问题。 const std::optional<std::string>不包含const std::string-它包含仅公开std::string访问的const。所以...从技术上说...但是实际上从来没有认真做过,这很糟糕...这是明确定义的:

const std::optional<std::string> opt("hello"s);
const_cast<std::string&>(opt.value()) = "I am a bad person and I feel bad"s;

因为string本身从未创建为const