The minimal example I got is a bit more complicated:
struct A { }; template <int> struct Parent { }; template <int N> constexpr int operator*(A, Parent<N>*) { return N; } template <class T> using ptr = T*; template <int> struct Other { }; template <int N> struct Kid: Parent<N> { static Other<A{} * ptr<Kid>{}> o; }; int main() { Kid<2>{}; }
[gcc] compiles the code without any problems, [clang] complains about matching the Parent problem with Kid :
prog.cc:7:15: note: candidate template ignored: could not match 'Parent' against 'Kid' constexpr int operator*(A, Parent<N>*) { return N; }
To become more absurd when we change the code a bit:
struct A { }; template <int> struct Parent { }; template <int N> constexpr int operator*(A, Parent<N>*) { return N; } template <class T> using ptr = T*; template <int> struct Other { }; template <int N> struct Kid: Parent<N> { static constexpr int s = A{} * ptr<Kid>{}; }; int main() { Other<Kid<2>::s>{}; }
[clang] also compiles code. So ... is this a mistake, or am I starting to go crazy?
c ++ language-lawyer constexpr incomplete-type template-deduction
Wf
source share