返回时不允许隐式转换

dar*_*une 25 c++ language-lawyer implicit-conversion c++17

#include <optional>

bool f() {
  std::optional<int> opt;
  return opt;
}
Run Code Online (Sandbox Code Playgroud)

不编译: 'return': cannot convert from 'std::optional<int>' to 'bool'

咨询参考我本来想找到一个解释,但我读了它应该没问题。

每当在不接受该类型但接受其他类型 T2 的上下文中使用某种类型 T1 的表达式时,就会执行隐式转换;特别是:

  • 当调用以 T2 为参数声明的函数时,将表达式用作参数时;
  • 当表达式用作操作数时,运算符需要 T2;
  • 初始化 T2 类型的新对象时,包括返回 T2 的函数中的 return 语句;
  • 当表达式用于 switch 语句时(T2 是整型);
  • 当表达式用于 if 语句或循环时(T2 是 bool)。

Sne*_*tel 24

std::optional没有任何隐式转换为bool. (允许隐式转换bool通常被认为是一个坏主意,因为它bool是一个整数类型,所以类似的东西int i = opt会编译并做完全错误的事情。)

std::optional 确实有一个到 bool 的“上下文转换”,其定义看起来类似于强制转换运算符:explicit operator bool()。这不能用于隐式转换;它仅适用于某些特定情况,其中预期的“上下文”是布尔值,例如 if 语句的条件。

你想要的是opt.has_value().


Nut*_*ker 5

来自 C++文档

当可选类型的对象根据上下文转换为 bool 时,如果该对象包含值,则转换返回 true;如果不包含值,则转换返回 false。

在这里阅读有关上下文转换的信息:

在以下上下文中,需要 bool 类型,并且如果声明 bool t(e); 则执行隐式转换。格式良好(即考虑显式转换函数,例如显式 T::operator bool() const; )。据说这样的表达式 e 根据上下文转换为 bool。

  • if、while、for 的控制表达式;
  • 内置逻辑运算符 !、&& 和 || 的操作数;
  • 条件运算符 ?:; 的第一个操作数
  • static_assert 声明中的谓词;
  • noexcept 说明符中的表达式;
  • 显式说明符中的表达式;

您可以执行以下操作:

bool f() {
    std::optional<int> opt;
    return opt || false;
}
Run Code Online (Sandbox Code Playgroud)

因为上下文转换发生在内置逻辑运算符的情况下,但上下文转换不包括语句return,并且std::optional其本身不具有到 的隐式转换bool

因此,最好使用std::optional<T>::has_value

bool f() {
    std::optional<int> opt;
    return opt.has_value();
}
Run Code Online (Sandbox Code Playgroud)

  • @darune `return {opt};` 不起作用,但 `return static_cast&lt;bool&gt;(opt);` 或 `return bool{opt};` 可以。但是,建议使用“has_value”成员函数,因为它确实显示了您想要做什么的明确意图 (4认同)