0

我有一个模板类

template<int N>
class xyz{
some code ....
};

如果我不在类中使用 N,那么无论模板值如何,此类的所有对象都应该兼容。但它不是。

例如,如果我说xyz<20> athen xyz<30> b(a),编译器会报错。

为什么会这样?

4

5 回答 5

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;
于 2012-12-04T12:43:26.263 回答
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.

就像您不能将fooor分配bar给同一个变量(因为它们的类型不同),您不能混合xyz<0>和的实例xyz<1>

如果你想这样做,你应该考虑使用经典继承。

于 2012-12-04T12:51:58.017 回答
1

模板类型等效规则明确写在标准中(第 14.4 段)。一条规则规定:

两个模板 ID 引用同一个类或函数,如果

  • 它们对应的整数或枚举类型的非类型模板参数具有相同的值

因此,不同的数字模板参数将产生不同的类型,无论它们是否实际使用。在后一种情况下,您可能希望使用模板复制构造函数:

template<int N>
class xyz{

  template<int M>
  xyz::xyz(const xyz<M>&);

};
于 2012-12-04T12:59:51.897 回答
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;
  }
};
于 2012-12-04T12:55:53.433 回答
0

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.

于 2012-12-04T12:47:59.123 回答