Type conversion at template non-type argument without constexpr

前端 未结 3 1531
天涯浪人
天涯浪人 2021-01-13 04:55

Consider the following code:

struct A {
    constexpr operator int() { return 42; }
};

template 
void foo() {}

void bar(A a) {
    foo(         


        
相关标签:
3条回答
  • 2021-01-13 05:15

    I would say that Clang is correct.

    Draft for current C++ (n4296) says:

    14.3.2 Template non-type arguments [temp.arg.nontype]

    A template-argument for a non-type template-parameter shall be a converted constant expression (5.20) of the type of the template-parameter

    And 5.20 §4 says (emphasize mine):

    5.20 Constant expressions [expr.const]

    ...

    (4) A converted constant expression of type T is an expression, implicitly converted to type T, where the converted expression is a constant expression and the implicit conversion sequence contains only

    (4.1) — user-defined conversions, ...

    IFAIK in foo<a>(); a is converted to int with a constexpr user-defined conversion and as such is a converted constant expression.

    That being said, we are not far from a edge case here, and my advice would be: do not play with such a construct in production code :-)

    0 讨论(0)
  • 2021-01-13 05:21

    The user-defined conversion is allowed by [expr.const]/(4.1), and I don't see a single applicable bullet point in [expr.const]/2 that would prevent your expression from being a constant one. In fact, the requirements are so loose that declaring a as

    A a;
    

    is still giving a well-formed program, even if a didn't have a constexpr default constructor etc., since the conversion operator is constexpr and no members are evaluated.

    As you saw yourself, GCC is contradictory in that it allows a in the static_assert condition but not a template-argument.

    0 讨论(0)
  • 2021-01-13 05:27

    As @Jarod42 suggests a should be constexpr. This is because templates are deduced at compile time, and so non-type arguments also have to be available at compile time. constexpr is a promise that they will be available at compile time.

    0 讨论(0)
提交回复
热议问题