jeudi 24 mai 2018

Using function argument as part of a constant expression - gcc vs clang

Consider the following code snippet:

template <bool> struct B { };

template <typename T>
constexpr bool pred(T t) { return true; } 

template <typename T>
auto f(T t) -> decltype(B<pred(t)>{})
{
}

  • clang++ (trunk) compiles the code

  • g++ (trunk) fails compilation with the following error:

    src:7:34: error: template argument 1 is invalid
    auto f(T t) -> decltype(B<pred(t)>{})
                                    ^
    
    src:7:34: error: template argument 1 is invalid
    src:7:34: error: template argument 1 is invalid
    src:7:34: error: template argument 1 is invalid
    src:7:34: error: template argument 1 is invalid
    src:7:34: error: template argument 1 is invalid
    src:7:25: error: invalid template-id
    auto f(T t) -> decltype(B<pred(t)>{})
                            ^
    
    src:7:36: error: class template argument deduction failed:
    auto f(T t) -> decltype(B<pred(t)>{})
                                        ^
    
    src:7:36: error: no matching function for call to 'B()'
    src:1:24: note: candidate: 'template<bool <anonymous> > B()-> B<<anonymous> >'
    template <bool> struct B { };
                            ^
    
    src:1:24: note:   template argument deduction/substitution failed:
    src:7:36: note:   couldn't deduce template parameter '<anonymous>'
    auto f(T t) -> decltype(B<pred(t)>{})
                                        ^
    
    

    live example on godbolt.org


Even though g++'s diagnostic is misleading, I assume that the problem here is that t is not a constant expression. Changing the code to...

decltype(B<pred(T{})>{})

...fixes the compilation error on g++: live example on godbolt.org


What compiler is behaving correctly here?

Aucun commentaire:

Enregistrer un commentaire