g++ c++17 class template argument deduction not working in a very specific case

  • A+
Category:Languages

I have the following code:

template <class T> class lit { public:     lit(T l) : val(l) {}     T val; };  template <class T> class cat { public:     cat(lit<T> const& a, lit<T> const& b) : a(a), b(b) {}     lit<T> const& a;     lit<T> const& b; };  template <class T> cat<T> operator+(lit<T> const& a, lit<T> const& b) {     return cat(a, b); }  int main() {     auto r1 = cat((lit      ('b')),  lit('d')); // compiles     auto r2 =     (lit      ('b')) + lit('d') ; // doesn't compile     auto r3 =      lit      ('b')  + lit('d') ; // compiles     auto r4 =     (lit      ('b'))            ; // compiles     auto r5 =     (lit<char>('b')) + lit('d') ; // compiles } 

This compiles fine with clang (as I would expect), but gcc produces the following error:

prog.cc: In function 'int main()': prog.cc:23:20: error: missing template arguments after 'lit'      auto r2 =     (lit      ('b')) + lit('d') ; // doesn't compile                     ^~~ prog.cc:2:7: note: 'template<class T> class lit' declared here  class lit : public ExpressionBuilder<T> {        ^~~ 

It seems to not be able to figure out the class template deduction from the constructor only in one very specific case (r2). I am assuming gcc is wrong, but can someone explain why it would fail only in this very specific case?

Example here: https://wandbox.org/permlink/jQCOhXFFQekS17Y1

 


This is a brand new feature in C++17, and therefore brand new in GCC. The pattern you've observed — or lack thereof — looks very much like a compiler bug. The way that it is triggered apparently randomly also fits that pattern.

Delving further into the exact hows and whys is a tedious job for the GCC devs, not for a Stack Overflow answer, as it's likely to be extraordinarily complex… but the correct approach now is to raise a bug and watch what happens. (OP has now done that, as bug 87709.)

Related examples do already exist on Bugzilla.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: