views:

87

answers:

1
A: 

This is because the argument type, DerivedB<DerivedA<double> > is not a derived class of BaseB<bderived1, BaseA<aderived1,datatype> >: The arguments of operator+ have for their base class's second template argument passed the type DerivedA<double> (which is datatype) but the operator+'s function parameter specifies BaseA<aderived1,datatype> as second template argument.

Since with these many types in there it's quite convoluted, let's make a simplier example

template<typename T>
struct B { };

template<typename T>
struct D : B<T> { };

struct base { };
struct derived : base { };

Now, let's see how these behave

template<typename T>
void f(B<T> const&);

void g(B<base> const&);
void h(B<derived> const&);

int main() {
  D<derived> dd;
  f(dd); // works, like your first case
  h(dd); // works too (just not deduced).

  g(dd); // does *not* work, just like your second case
}

The C++ Standard specifies that derived->base conversions are considered when matching a deduced function parameter type. That's why file << "hello" works: The operator is defined in terms of basic_ostream<C,T> even though file really could be an basic_fstream (derived class of it). This applies in your first case. But in your second case you try to deduce a parameter that's entirely not a base class of the argument passed.

Johannes Schaub - litb