Reputation: 1542
The following code doesn't compile.
class A {};
class B: public A {};
class C: public A {};
template<typename T>
void do_op(T in, T out) {}
int main(int argc, char *argv[]) {
B b;
C c;
do_op(b, c);
}
My question is, why templates do not deduce that there is common ancestor ?
Upvotes: 0
Views: 35
Reputation: 6131
Templates deduce the types they are given, fitting the patterns provided (const, volatile, refs, ptr, etc). They do not convert a T to an A for the same reason they do not convert ints to longs or chars to bools.
If you want do_op() to take and operate on base class references, they why not write it to take base class references:
void do_op(A const & in, A & out) { ... }
Upvotes: 1
Reputation: 93264
why templates do not deduce that there is common ancestor ?
They were simply not designed with that it mind - it would introduce significant additional complexity and make it easier to write incorrect code (e.g. object slicing). The behavior you noticed is also consistent with the fact that template argument deduction doesn't take implicit conversions into account.
You can (and IMHO, should) take two different template parameters:
template<typename T, typename U>
void do_op(T in, U out) {}
Or, if you really know what you're doing...
do_op<A>(b, c);
Upvotes: 4