Calling constexpr in default template argument

后端 未结 2 1708
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-04 01:40

In C++11 I am using a constexpr function as a default value for a template parameter - it looks like this:

template 
struct bar
{
    static         


        
相关标签:
2条回答
  • 2020-12-04 02:17

    Richard Smith (zygoloid) at the LLVM IRC channel had a short talk with me about this issue which is your answer

    <litb> hello folks
    <litb> zygoloid, what should happen in this case?
    <litb> http://stackoverflow.com/questions/10721130/calling-constexpr-in-default-template-argument
    <litb> it seems to be clang's behavior is surprising
    <litb> zygoloid, i cannot apply the "point of instantiation" rule to constexpr 
      function templates. if i call such a function template, the called definition's 
      POI often is *after* the specialization reference, which means at the point of 
      the call, the constexpr function template specialization is "undefined".
    <zygoloid> it's a horrible mess. Clang does not do what the standard intends, but 
      as you note, the actual spec is gloriously unclear
    <d0k> :(
    <zygoloid> we should instantiate bar<3>::get(), because it is odr-used, but we 
      don't, because we incorrectly believe it's used in an unevaluated context
    <zygoloid> conversely, the point of instantiation is too late :/
    <zygoloid> PR11851
    

    So it seems that sometimes, Clang instantiates called function templates or member function of class templates but their instantiation is too late for the call to see, and at other cases it doesn't even instantiate them because it thinks it will never need them (unevaluated context).

    0 讨论(0)
  • 2020-12-04 02:21

    I think GCC Clang is correct

    quoted from n3290:

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

    1. A template-argument for a non-type, non-template template-parameter shall be one of:
      • for a non-type template-parameter of integral or enumeration type, a converted > constant expression (5.19) of the type of the template-parameter; or
      • ...

    EDIT: 5.19 3

    A literal constant expression is a prvalue core constant expression of literal type, but not pointer type. An integral constant expression is a literal constant expression of integral or unscoped enumeration type. [ Note: Such expressions may be used as array bounds (8.3.4, 5.3.4), as bit-field lengths (9.6), as enumerator initializers if the underlying type is not fixed (7.2), as null pointer constants (4.10), and as alignments (7.6.2). —end note ] A converted constant expression of type T is a literal constant expression, implicitly converted to type T, where the implicit conversion (if any) is permitted in a literal constant expression and the implicit conversion sequence contains only user-defined conversions, lvalue-to-rvalue conversions (4.1), integral promotions (4.5), and integral conversions (4.7) other than narrowing conversions (8.5.4).

    [ Note: such expressions may be used as case expressions (6.4.2), as enumerator initializers if the underlying type is fixed (7.2), and as integral or enumeration non-type template arguments (14.3). —end note ]

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