用于错误检查的转换函数考虑好了吗?

2021-12-26 00:00:00 error-handling c++

我想要一种简单的方法来检查对象是否有效.我想到了一个简单的转换函数,像这样:

I'd like to have a simple way of checking for an object to be valid. I thought of a simple conversion function, something like this:

operator bool() const { return is_valid; }

现在检查它是否有效很简单

Checking for it to be valid would be very simple now

// is my object invalid?
if (!my_object) std::cerr << "my_object isn't valid" << std::endl;

这被认为是一种好习惯吗?

Is this considered a good practise?

推荐答案

在 C++03 中,您需要使用 安全布尔习语 避免邪恶的事情:

In C++03, you need to use the safe bool idiom to avoid evil things:

int x = my_object; // this works

在 C++11 中,您可以使用显式转换:

In C++11 you can use an explicit conversion:

explicit operator bool() const
{
    // verify if valid
    return is_valid;
}

这样你就需要明确转换为 bool,这样你就不会再意外地做疯狂的事情(在 C++ 中,你总是可以故意做疯狂的事情):

This way you need to be explicit about the conversion to bool, so you can no longer do crazy things by accident (in C++ you can always do crazy things on purpose):

int x = my_object; // does not compile because there's no explicit conversion
bool y = bool(my_object); // an explicit conversion does the trick

这在ifwhile 等需要布尔表达式的地方仍然正常工作,因为这些语句的条件是上下文转换布尔:

This still works as normal in places like if and while that require a boolean expression, because the condition of those statements is contextually converted to bool:

// this uses the explicit conversion "implicitly"
if (my_object)
{
    ...
}

这在 §4[conv] 中有记录:

表达式 e 可以隐式地表示转换为类型T当且仅当声明 T t=e; 格式良好,对于一些发明的临时变量 t(§8.5).某些语言结构要求表达式为转换为布尔值.一个表达式 e 出现在这样的上下文被认为是上下文转换为 bool 并且格式良好当且仅当声明 bool t(e); 格式正确,对于某些发明了临时变量 t (§8.5).两者的影响隐式转换与执行相同声明和初始化,然后使用临时作为转换结果的变量.

An expression e can be implicitly converted to a type T if and only if the declaration T t=e; is well-formed, for some invented temporary variable t (§8.5). Certain language constructs require that an expression be converted to a Boolean value. An expression e appearing in such a context is said to be contextually converted to bool and is well-formed if and only if the declaration bool t(e); is well-formed, for some invented temporary variable t (§8.5). The effect of either implicit conversion is the same as performing the declaration and initialization and then using the temporary variable as the result of the conversion.

(区别在于使用 bool t(e); 而不是 bool t = e;.)

(What makes the difference is the use of bool t(e); instead of bool t = e;.)

发生这种上下文转换到 bool 的地方是:

The places were this contextual conversion to bool happens are:

  • ifwhilefor语句的条件;
  • 逻辑否定运算符!、逻辑与运算符&&、逻辑析取运算符||;
  • 条件运算符?:;
  • static_assert 的条件;
  • noexcept 异常说明符的可选常量表达式;
  • the conditions of if, while, and for statements;
  • the operators of logical negation !, logical conjunction &&, and logical disjunction ||;
  • the conditional operator ?:;
  • the condition of static_assert;
  • the optional constant expression of the noexcept exception specifier;

相关文章