假设我们有基类表
template <typename T>
class Table
{
public:
Table();
virtual ~Table() = default;
private:
// get all column names as list
virtual std::list<std::string> getAllColumnsImpl();
};
我希望继承基类的TestTable类和覆盖方法 getAllColumnsImpl :
class TestTable :
public Table<TestTable>
{
public:
TestTable();
virtual ~TestTable() = default;
std::string Description;
int Count;
private:
// get all column names as list
std::list<std::string> getAllColumnsImpl() override;
};
一般可以吗?
例如,我有链接器错误,如:
error LNK2019: unresolved external symbol "public: __cdecl Table<class TestTable>::Table<class TestTable>(void)" (??0?$Table@VTestTable@@@@QEAA@XZ) referenced in function "public: __cdecl TestTable::TestTable(void)" (??0TestTable@@QEAA@XZ)
答案 0 :(得分:1)
你可以这样做,它被称为CRTP - 奇怪的重复模板参数。它非常方便,有很多博客和资源可以解释它的用途。
您得到的错误是因为您需要在模板的头文件中包含模板的函数体。
每个cpp文件都编译为单独的目标文件,并且基于per-cpp文件解析模板。当您将模板代码放入cpp文件中时,它只是“模板&lt; T&gt;”并且编译器不知道T是什么,因此不会生成任何代码(除非它是从同一个cpp文件请求的,具有实际类型而不是T)。
但是,你的另一个cpp文件知道它需要一个“模板&lt; TestTable&gt;”,但是它无法访问那些能够起作用的代码,因为它只停留在另一个cpp文件中,知道通用的“模板&lt; T&gt;”。两个cpp文件都不能生成丢失的代码,因此您会收到链接器错误。将所有模板代码放在头文件中可以解决问题。