我有一个模板类
template<int N>
class xyz{
some code ....
};
如果我不在类中使用N,那么无论模板值如何,此类的所有对象都应该是兼容的。但事实并非如此。
例如,如果我说xyz<20> a
然后xyz<30> b(a)
,则编译器会出错。
为什么会这样?
答案 0 :(得分:3)
因为它们是不同的类型。即使是这个空类模板
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;
答案 1 :(得分:1)
每次使用不同的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
或bar
分配给同一个变量(因为它们的类型不同),您无法混合xyz<0>
和xyz<1>
的实例。
如果你想这样做,你应该考虑使用经典继承。
答案 2 :(得分:1)
模板类型等价规则在Standart中明确写出(第14.4段)。一条规则规定:
如果
,则两个模板ID引用相同的类或函数
- 其对应的整数或枚举类型的非类型模板参数具有相同的值
因此,不同的数字模板参数将产生不同的类型,无论它们是否实际使用。在后一种情况下,您可能希望使用模板复制构造函数:
template<int N>
class xyz{
template<int M>
xyz::xyz(const xyz<M>&);
};
答案 3 :(得分:0)
您希望编译器如何证明这一点?
考虑:
template<int N>
class xyz{
void foo () {external_function (N);}
};
你建议编译器去查看external_function
做什么吗?
除了编译器在N的grdounds上产生兼容类型之外,不会被用作维护噩梦。
答案 4 :(得分:0)
当你说兼容时,我认为你的意思是“可复制和可分配”。
您需要定义复制构造函数和赋值运算符 处理用任意值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;
}
};