------- 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