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
是由一个更通用的模板继承的呢?@Brian
Base
是一个库的一部分,我无法控制它,但我想要它提供的其他功能。你知道真正有趣的是什么吗?注释掉
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";