使用不受支持的类型

时间:2016-11-29 21:19:49

标签: c++ templates inheritance

我有一个模板Base类,我想继承它。 Base类有一个公共方法,它假设模板类型。代码的简化版本如下:

#include <iostream>

using namespace std;

template <typename V>
class Base {
 public:
  virtual void print() {
    a = "a";
    cout << "Base class" ;
  }
  void callIt() {
    print();
  }
  V a;
};

class Derived : public Base<int> {
 public:
  void print() override {
    cout << "Derived class\n";
  }
};


int main() {
  Derived d;
  d.callIt();
  return 0;
}

使用GCC 6.2.0编译此代码会出现此错误:

test.cpp: In instantiation of 'void Base<V>::print() [with V = int]':
test.cpp:13:10:   required from 'void Base<V>::callIt() [with V = int]'
test.cpp:28:12:   required from here
test.cpp:9:7: error: invalid conversion from 'const char*' to 'int' [-fpermissive]
     a = "a";
     ~~^~~~~

我想从编译器中完全隐藏Base方法的print()类实现。我怎么能这样做?

编辑:具有讽刺意味的是,注释掉行a = "a";可以让代码成功编译并打印出Derived class

3 个答案:

答案 0 :(得分:4)

如果在声明Base<int>::print()之前为Derived添加专门化,则可以使代码正常工作:

#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;
}

Live Demo

小心这样做:它打破了Base的作者关于哪些类型与模板一起工作的假设,并且很容易导致库代码中难以追踪的错误。

答案 1 :(得分:2)

由于print是虚拟的,因此只要从Base继承,就必须实例化它(因为编译器需要生成适当的vtable) - 即使函数尚未被调用。如果print是非虚拟成员,则情况并非如此 - 在这种情况下,只有在被调用时才会实例化。

我能想到的唯一解决方案是看看你是否可以在这里摆脱虚拟功能 - 如果你不能,抱歉,你运气不好。

答案 2 :(得分:0)

简化以解决问题:

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";

当然这是一个错误,因为您无法将const char*分配给int

因此,在此处得出的唯一合理结论是,Base<T>的设计遵循约束条件,即必须存在从const char*T的可访问转化。

如果你想让T成为其他东西,那么这个基类是不合适的,你需要找到另一种方法来实现你想要的东西(封装?)。