什么时候可以在不进行强制转换的情况下使用显式运算符 bool?

When can I use explicit operator bool without a cast?

我的 class 已显式转换为 bool:

struct T {
    explicit operator bool() const { return true; }
};

我有一个实例:

T t;

要将其赋值给bool类型的变量,我需要写一个强制转换:

bool b = static_cast<bool>(t);
bool b = bool(t);
bool b(t);  // converting initialiser
bool b{static_cast<bool>(t)};

我知道尽管有 explicit 限定符,但我可以在条件中直接使用我的类型而无需强制转换:

if (t)
    /* statement */;

我还能在哪里使用 t 作为 bool 而无需强制转换?

标准提到值可能 " 上下文转换为 bool" 的地方。他们分为四大类:

声明

  •    if (t) /* statement */;
    
  •    for (;t;) /* statement */;
    
  •    while (t) /* statement */;
    
  •    do { /* block */ } while (t);
    

表达式

  •    !t
    
  •    t && t2
    
  •    t || t2
    
  •    t ? "true" : "false"
    

编译时测试

  •    static_assert(t);
    
  •    noexcept(t)
    
  •    explicit(t)
    
  •    if constexpr (t)
    

对于这些,转换运算符需要 constexpr

算法和概念

  •    NullablePointer T
    

    标准要求满足此概念的类型的任何地方(例如 std::unique_ptrpointer 类型),都可以根据上下文进行转换。此外,NullablePointer 的等式和不等式运算符的 return 值必须可根据上下文转换为 bool.

  •    std::remove_if(first, last, [&](auto){ return t; });
    

    在任何带有名为 PredicateBinaryPredicate 的模板参数的算法中,谓词参数可以 return 和 T.

  •    std::sort(first, last, [&](auto){ return t; });
    

    在任何带有名为 Compare 的模板参数的算法中,比较器参数可以 return 和 T.

(source1, source2)


请注意混合使用 const 和非常量转换运算符可能会造成混淆: