以下代码无法编译。
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);
}
我的问题是,为什么模板不能推断出有共同的祖先?
答案 0 :(得分:4)
为什么模板不能推断出有共同的祖先?
它们的设计并没有考虑它 - 它会带来显着的额外复杂性,并且更容易编写错误的代码(例如对象切片)。您注意到的行为也与模板参数推断不会将隐式转换考虑在内的事实一致。
你可以(和恕我直言,应该)采用两个不同的模板参数:
template<typename T, typename U>
void do_op(T in, U out) {}
或者,如果你真的知道自己在做什么......
do_op<A>(b, c);
答案 1 :(得分:1)
模板推断出它们的类型,适合所提供的模式(const,volatile,refs,ptr等)。它们不会将T转换为A,原因与它们不将int转换为long或chars to bools的原因相同。
如果你想让do_op()接受并操作基类引用,那么为什么不写它来获取基类引用:
void do_op(A const & in, A & out) { ... }