我有一个模板类
template<int N>
class xyz{
some code ....
};
如果我不在类中使用 N,那么无论模板值如何,此类的所有对象都应该兼容。但它不是。
例如,如果我说xyz<20> a
then xyz<30> b(a)
,编译器会报错。
为什么会这样?
我有一个模板类
template<int N>
class xyz{
some code ....
};
如果我不在类中使用 N,那么无论模板值如何,此类的所有对象都应该兼容。但它不是。
例如,如果我说xyz<20> a
then xyz<30> b(a)
,编译器会报错。
为什么会这样?
因为它们是不同的类型。即使对于这个空的类模板
template <int N> struct Foo {};
Foo<1>
是不同的类型Foo<2>
。当使用模板参数实例化这样的模板时,它会创建一个不同的类,而不管该模板参数是否在类的代码中使用。类模板是根据一些(模板)参数构建类的配方(模板)。
现在,如果您希望能够Foo
从另一个实例构造一个实例,那么您可以添加一个隐式转换构造函数:
template <int N>
struct Foo
{
template <int M> Foo(const Foo<M>& rhs) {}
};
然后你可以在一个和另一个之间隐式转换:
Foo<42> a;
Foo<1> b (a);
Foo<99> c;
c = b;
每次使用不同的值时N
,编译器都会创建一个新的类定义。使用模板值或不改变什么。
函数参数也是一样的:
int foo(void) { // foo is of type `int (*)()`
return 1;
}
int bar(int not_used) { // bar is of type `int (*)(int)`
return 1;
}
bar
不要使用参数,但它的签名与foo
.
就像您不能将foo
or分配bar
给同一个变量(因为它们的类型不同),您不能混合xyz<0>
和的实例xyz<1>
。
如果你想这样做,你应该考虑使用经典继承。
模板类型等效规则明确写在标准中(第 14.4 段)。一条规则规定:
两个模板 ID 引用同一个类或函数,如果
- 它们对应的整数或枚举类型的非类型模板参数具有相同的值
因此,不同的数字模板参数将产生不同的类型,无论它们是否实际使用。在后一种情况下,您可能希望使用模板复制构造函数:
template<int N>
class xyz{
template<int M>
xyz::xyz(const xyz<M>&);
};
当您说兼容时,我假设您的意思是“可复制并相互分配”。
您将需要定义复制构造函数和赋值运算符来处理用任意 int 值实例化的类。
template<int N>
class Foo {
public:
template<int NO>
Foo(const Foo<NO>& other) {
// do stuff
}
template<int NO>
Foo& operator=(const Foo<NO>& other) {
// do stuff
return *this;
}
};
How do you want compiler to prove that?
Consider:
template<int N>
class xyz{
void foo () {external_function (N);}
};
Do you suggest compiler to go and check what external_function
does?
Besides having compiler produce compatible types on the grdounds of N not being used would have been a maintanence nightmare.