C++ 模板类对象兼容

c++ template class objects compatible

本文关键字:对象 C++      更新时间:2023-10-16

我有一个模板类

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

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

例如,如果我说xyz<20> a然后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 不同。

就像您不能将foobar分配给同一个变量一样(因为它们的类型不同),您也不能混合使用 xyz<0>xyz<1> 的实例。

如果要执行此操作,请考虑使用经典继承。

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

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

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

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

template<int N>
class xyz{
  template<int M>
  xyz::xyz(const xyz<M>&);
};

您希望编译器如何证明这一点?

考虑:

template<int N>
class xyz{
void foo () {external_function (N);}
};

你建议编译器去检查external_function做什么吗?

除了让编译器在不使用的 N 的 grdounds 上生成兼容的类型之外,维护将是一场维护噩梦。

当你说兼容时,我假设你的意思是"可复制可构造和彼此可分配"。

您需要定义复制构造函数和赋值运算符处理使用 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;
  }
};