何时可以使用不强制转换的显式bool操作符?

When can I use explicit operator bool without a cast?

本文关键字:bool 操作符 转换 可以使 何时      更新时间:2023-10-16

我的类有一个显式的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的相等和不等操作符的返回值必须在上下文中转换为bool

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

    在任何具有模板形参PredicateBinaryPredicate的算法中,谓词实参都可以返回T

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

    在任何具有模板形参Compare的算法中,比较器实参都可以返回T

(source1 source2)


请注意const和非const转换操作符的混合使用可能会导致混淆:

  • 为什么在上下文转换中不显式bool()转换?
  • 为什么explicit operator bool没有像预期的那样生效?