C++模板类专用化:为什么需要重新实现常见方法
C++ template class specialization: why do common methods need to be re-implemented
在示例中:
#include <iostream>
using namespace std;
class B
{
public:
virtual void pvf() = 0;
};
template <class T>
class D : public B
{
public:
D(){}
virtual void pvf() {}
private:
string data;
};
template <>
class D<bool> : public B
{
public:
D();
virtual void pvf(){ cout << "bool type" << endl; }
};
int main()
{
D<int> d1;
D<bool> d2;
}
我得到以下错误:
test.cpp:(.text+0x1c): undefined reference to `D<bool>::D()'
注意,我不只是专门化D()本身的原因是,我想在D<bool>
的情况下消除对字符串D<T>::data
的需要
为什么我需要在D<bool>
中重新实现D()
?似乎应该有一种方法让编译器使用D<T>
的版本。
有没有什么方法可以在不需要重新实现方法的情况下完成这样一个简单的专业化?
类模板的每个专业化都会产生不同的类-它们之间不共享任何成员。由于您已经明确地专门化了整个类,因此您不会从模板中获得任何成员,必须全部实现它们。
您可以明确地专门针对单个成员,而不是整个类别:
template <> void D<bool>::pvf(){ cout << "bool type" << endl; }
然后D<bool>
将仍然包含类模板中所有您尚未明确指定的成员,包括默认构造函数。
不,没有。
专业化的表现与继承截然不同。它与通用模板版本没有连接。
当您使用/实例化模板时,编译器将创建一个新的类型名称,然后查找如何定义此类型。当它找到一个特殊化时,它会将其作为新类型的定义。如果没有,它会获取通用模板并实例化它
因此,它们没有连接,您只是在编写一个全新的类,只是为编译器提供一个特殊的名称,以防有人使用/实例化模板以该名称查找它。
问题是您错误地认为D<A>
和D<B>
之间有任何公共。模板实例是类型,两个不同的实例是两种不同的类型,故事结束。只有当相同模板的实例具有形式上相似的代码时,才会发生这种情况,但通过专门化,您可以定义任何您喜欢的类型。简而言之,您显式定义的每个类型都是完全独立的,并且在专门的模板实例之间没有通用性,即使它们碰巧具有相同的名称。
例如:
template <typename T> struct Foo
{
T & r;
const T t;
void gobble(const T &);
Foo(T *);
};
template <> struct Foo<int>
{
std::vector<char> data;
int gobble() const;
Foo(bool, int, Foo<char> &);
};
类型Foo<char>
和Foo<int>
彼此无关,也没有理由让其中一个的任何部分在另一个内部有任何用途。
如果你想排除常见的功能,可以使用私有继承:
template <typename> struct D : private DImpl { /* ... */ }
您需要重新实现它,因为D<T>
和D<bool>
是完全不相关的类(它们只是碰巧"共享名称")。模板就是这样工作的。
如果您希望类共享构造代码,只需将该代码放入B::B
中即可(即,每次您希望在同一层次结构的不同分支中重用代码时所做的相同操作:向上移动代码,让继承处理其余部分)。
考虑D<T>::D()
将负责默认构造string data
,而D<bool>
没有任何这样的成员。显然,在每种情况下都无法使用相同的已发出代码。
但是,如果您的默认构造函数什么都不做(在的版本中),只需省略它,并允许编译器完成工作。
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- C++ 如何使用动态计算的新节点实现 A*?
- 实现一个函数,该函数将字符串作为输入并返回一个新字符串,辅音字母不替换为 "!"
- C++ 多重继承:使用基类 A 的实现实现基类 B 的抽象方法
- 为什么这个新的 [ ] 和删除 [ ] 实现会分解为 12 >整数?
- 在不创建新节点的情况下实现带有映射的trie
- 使用 Qt5 的新信号/插槽实现向滑块发出信号
- 如何实现由TPAINTBOX创建的新组件的OnMousedown,OnMouseUp事件
- 如何自己为我自己的shared_ptr实现实现别名构造函数
- 为什么我不能使私人运营商成为新的并使用默认实现?
- 如何向 C++ 中无法访问其实现的类添加新函数
- 在哪里可以找到C 中新运营商的确切实现
- C++新的不同实现
- 如何实现一个创建新对象并返回对它的引用的C++方法
- 如何实现消费者生产者,消费者可以请求新的数据
- 这个UTF-8实现实现是定义的还是定义良好的
- 如何实现C++"新"运算符
- 我可以在不使用新关键字的情况下以某种方式实现这一点吗?C++
- 如何实现一个简单的容器放置新和放置功能
- 您将如何重构这种多态设计,以便在添加新实现时使其更加灵活?