代码之家  ›  专栏  ›  技术社区  ›  Silicomancer

constexpr条件不是常数?

  •  0
  • Silicomancer  · 技术社区  · 6 年前

    constexpr bool gDebug = true;
    
    template <typename T> constexpr const T& Select(const bool pCondition, const T& a, const T& b)
    {
       if constexpr (pCondition)
       {
          return a;
       }
       else
       {
          return b;
       }
    }
    

    然后我这样称呼它:

    int c = Select<QString>(gDebug, a, b); // In .cpp
    

    error: ‘pCondition’ is not a constant expression 对于 if constexpr

    为什么?这不管用吗?

    2 回复  |  直到 6 年前
        1
  •  5
  •   Barry    6 年前

    为什么?这不管用吗?

    不,不应该。 pCondition 不是一个 constant expression . 我明白为什么这会让人困惑,因为 const -但术语常量表达式指的是能够在编译时对其求值。也就是说,不是 常数 constexpr .

    if constexpr 需要一个常量表达式,所以您只需要 if

    template <bool pCondition, typename T>
    constexpr const T& Select(const T& a, const T& b)
    {
       if constexpr (pCondition) // now okay
       {
          return a;
       }
       else
       {
          return b;
       }
    }
    
    int c = Select<qDebug>(a, b);
    

    或者,您可以要求参数是编码到类型中的值:

    template <typename Boolean, typename T>
    constexpr const T& Select(Boolean pCondition, const T&, const T&);
    
    constexpr std::true_type qDebug{}; // true_type, not bool = true
    int c = Select(qDebug, a, b);      // okay
    
        2
  •  1
  •   Patrick Fromberg    4 年前

    巴里是对的,但我认为这并不是你理解上的错误。

    template <typename T> constexpr const T& Select(const bool pCondition, const T& a, const T& b)
    

    这意味着,如果参数是可计算的,则函数调用在编译时是可计算的。但是,可以使用编译时未知的参数调用该函数。在这种情况下,函数调用本身不是一个常量表达式,将在运行时进行计算。从函数式编程的意义上讲,它仍然是纯粹的 noexcept

    但是 if constexpr (pCondition) {...

    因此,由于可以在编译时使用未知参数调用constexpr函数,因此它不能包含声明的表达式 constexpr 如果它们依赖于这些参数。