------- Additional Comments From reichelt at gcc dot gnu dot org 2004-10-22 15:28 ------- Here's something shorter:
================================================================ struct B {}; template<int> struct P; template<int I> P<I> operator* (const P<I>&, const P<I>&); template<int I> B operator+ (const P<I>&, const P<I>&); template<int> struct P { P(); P(const B&); friend P operator* <>(P const&, P const&); }; typedef P<2> poly; void foo() { poly x2, b, x, a; poly left = (x2 + b) * x + a; } ================================================================ I think gcc 3.4 is right: (x2+b) does not return a "poly" object, but an object of a different type ("B" in this example). This can be transformed into an object of type poly due to a suitable construction, but in template resolution no argument promotion is done. And there's no operator * matching the arguments (A,poly). The strange thing is that gcc 3.3.5 accepts the code. If I remove the friend declaration also gcc 3.3.5 complains. So I think this is only a bug in gcc 3.3.5 which got fixed already. If you agree, please close the PR. Btw, you can make the code compile by an explicit type conversion: poly left = poly(x2 + b) * x + a; -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18110