C++ 在C+中继承模板类+;使用不支持的类型
我有一个要继承的模板C++ 在C+中继承模板类+;使用不支持的类型,c++,templates,inheritance,C++,Templates,Inheritance,我有一个要继承的模板Base类。Base类有一个公共方法,该方法假设模板类型。代码的简化版本如下所示: #包括 使用名称空间std; 模板 阶级基础{ 公众: 虚拟空打印(){ a=“a”; cout由于您的print是虚拟的,因此无论何时从Base继承,都必须实例化它(因为编译器需要生成适当的vtable)-即使函数尚未调用。如果print是非虚拟成员,则不会发生这种情况-在这种情况下,只有在调用时才会实例化它 我能想到的唯一解决方案是看看你是否能在这里摆脱虚拟函数——如果不能,很抱歉,你就走
Base
类。Base
类有一个公共方法,该方法假设模板类型。代码的简化版本如下所示:
#包括
使用名称空间std;
模板
阶级基础{
公众:
虚拟空打印(){
a=“a”;
cout由于您的print
是虚拟的,因此无论何时从Base
继承,都必须实例化它(因为编译器需要生成适当的vtable)-即使函数尚未调用。如果print
是非虚拟成员,则不会发生这种情况-在这种情况下,只有在调用时才会实例化它
我能想到的唯一解决方案是看看你是否能在这里摆脱虚拟函数——如果不能,很抱歉,你就走运了。如果你在声明派生的之前为Base::print()
添加一个专门化,你的代码就可以正常工作了:
#include <iostream>
using namespace std;
template <typename V>
class Base {
public:
virtual void print() {
a = "a";
cout << "Base class" ;
}
void callIt() {
print();
}
V a;
};
template <>
void Base<int>::print() {
cout << "Specialization\n";
}
class Derived : public Base<int> {
public:
void print() override {
cout << "Derived class\n";
}
};
int main() {
Derived d;
d.callIt();
return 0;
}
#包括
使用名称空间std;
模板
阶级基础{
公众:
虚拟空打印(){
a=“a”;
不能简化以隔离问题:
template <typename V>
class Base {
public:
virtual void print() {
a = "a";
}
V a;
};
int main()
{
Base<int> b;
}
当然,这是一个错误,因为您不能将const char*
分配给int
因此,这里得出的唯一合理结论是,Base
的设计带有一个约束,即必须存在从const char*
到T
的可访问转换
如果您希望T
是其他类型,那么这个基类不合适,您需要找到另一种方法来实现您想要的(封装?).对不起,Base::print
为什么要假设V
如果Base
是由一个更通用的模板继承的呢?@BrianBase
是一个库的一部分,我无法控制它,但我想要它提供的其他功能。你知道真正有趣的是什么吗?注释掉a=“a”
并查看输出。(扰流板警报:输出是派生类
。什么??)@JackDeeth是的,这就是让我困惑的原因。我不认为隐藏Base::print
是您想要的,因为从那时起,它将无法使用基类调用。我认为您应该寻找的是在不受支持的情况下使其成为纯虚拟的。您是对的,但我认为我过于简化了代码。我刚刚更新了代码。print()Base::callIt()
正在调用Base::callIt()
。在旧代码中删除virtual会有帮助,但在新代码中不会。我尝试注释掉a=“a”
并编译代码,得到的是基类
,而不是派生类
。这个问题有什么解决方案吗?为什么Base::callIt()
needed?@Javad无法将其添加到Base
,调用d.print()
效果良好:因为它在OP的代码中。Base::callIt()
是OP无法从Base::print()中删除virtual
限定符的原因
。哦,对不起,我没有看到。但公平地说,在我将代码复制到Wandbox之后,它被编辑到了原始帖子中:)对不起,最初的版本过于简单了。
template <typename V>
class Base {
public:
virtual void print() {
a = "a";
}
V a;
};
int main()
{
Base<int> b;
}
<source>:5:7: error: invalid conversion from 'const char*' to 'int' [-fpermissive]
a = "a";
int a = "a";