C++ 模板类对象兼容
c++ template class objects compatible
我有一个模板类
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
不同。
就像您不能将foo
或bar
分配给同一个变量一样(因为它们的类型不同),您也不能混合使用 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;
}
};
相关文章:
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 提升 ASIO 无法识别计时器对象
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 如何返回一个类的两个对象相加的结果
- 使用std::函数映射对象方法
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 构造对象的歧义
- 使用"std::unordereded_map"映射到"std::list"对象