我认为
std::optional<const std::string>
允许为可选字段分配新值,但是无法更改字符串本身和输入值
const std::optional<const std::string>
不可能同时做。但是接下来呢?
const std::optional<std::string>
答案 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
。