【发布时间】:2020-07-13 01:15:23
【问题描述】:
我有一个实现许多功能的类模板。当声明特定类型时,我还希望能够添加此类的专用版本,该版本只有少数功能覆盖基类的功能。我知道我可以通过一个类模板和它的显式特化来实现这一点。不过我也想:
- 具有唯一命名的显式特化,类似于如何唯一命名基类和派生类。
- 从实例化的
Derived对象调用Base函数,可以在Derived函数内部,也可以如下使用obj1.Foo显式调用
这是我正在尝试制作的(简化的)示例代码:
在 myClasses.h 中
template<typename T>
class Base
{
public:
void Foo (T& input);
virtual void Bar (T& input);
}
template<>
class Derived : public Base<int>
{
public:
void Bar (int& input) override;
}
在 myClasses.cpp 中
template<typename T>
Base::Foo(T& input) { // Do something generic }
template<typename T>
Base::Bar(T& input) { // Do something generic }
template<>
Derived::Bar(int& input) { // Do something int-dependent }
在 main.cpp 中
int main()
{
Base<int> obj1 = new Derived();
obj1.Foo(input); // Runs Base::Foo
obj1.Bar(input); // Runs Derived::Bar
}
但是,此代码失败并出现 explicit specialization of non-template Derived 错误等。我已经阅读了很多 StackOverflow 线程来让我走到这一步,但我还没有找到任何可以帮助我进行编译的东西。所以我的问题是:
- 是否可以通过这种方式将类模板与类继承结合起来?
- 为什么编译器将派生类标记为非模板,尽管我明确使用了该关键字?
- 什么是使该代码工作的正确语法? (假设我正在尝试做的事情是可能的)
编辑: 按照 HTNW 的建议,我可以通过删除 template<> 前缀将 Derived 变为常规类。这将允许一切编译到obj1.Foo(input)。实例化的 Derived 类似乎无法找到或访问基 Foo 函数。
【问题讨论】:
-
您没有
Derived模板,只有专业化。需要有一个模板来专门... -
为什么你不能只制作
Derived...而不是模板?class Derived : public Base<int> { ... };。将模板与继承“结合”的唯一方法对我来说有意义,然后使用类型特征通过选择T:template<typename T> impl_for { using type = Base<T>; }; template<> impl_for<int> { using type = Derived; };来查找派生类。 -
@Matt ?您的意思是您未能构造
Derived类型的对象吗?那是因为new Derived()没有Derived类型:它在堆上分配Derived,在那里构造它,并返回指向它的Derived*。修复,从最差到最好:Base<int> *obj1 = new Derived();、std::unique_ptr<Base<int>> obj1 = std::make_unique<Derived>();、Base<int> &&obj = Derived();。请注意,第一个泄漏内存。这就是为什么你不应该使用new。 -
@Matt Base 的特化可以是,例如,
template<> Base<int>。这使您可以替换 Base 的定义,据说比一般模板提供的更适合整数。这对类模板很少有用,但有时对函数模板有用。 -
@ravnsgaard 恰恰相反——它对类更有用(例如,参见特征),但通常不建议专门化函数模板(重载是首选)。
标签: c++ templates template-specialization explicit-specialization