类模板成员函数的专用化

Specialization of member function of class template

本文关键字:专用 函数 成员      更新时间:2023-10-16

我有一个Base类,我把它用作树。从这个基类中,我派生了一个模板Container类,它应该能够容纳各种类型。我想给 Container 类一个toString函数,该函数将其值及其所有子项的值转换为字符串。Container<A>可以有不同类型的子Container<B>

我不知道该怎么做。下面是我的代码。

// File base.h:
class Base {
public:
virtual string toString();
protected:
vector<Base *> _children
}
// File base.cpp:
string Base::toString() {
string a="something"
return a;
}

然后我有一个模板化的派生类:

// File container.h:
template<class T>
class Container: public Base {
public:
string toString() override;
private:
T _data;
}

我想专门化 toString 函数,这样它就可以处理 不同类型:

File container.cpp:
template <class T>
string Container<T>::toString() {
string valueString = "not sure how to handle this type";
for(int i=0;i<_children.size;i++) {
valueString+=" "+_children[i]->toString();
}
return valueString;
}
template <>
string Container<int>::toString() {
string valueString = std::to_string(_data);
for(int i=0;i<_children.size;i++) {
valueString+=" "+_children[i]->toString();
}
return valueString;
}

我也为Base类提供了一个toString函数,因为我不知道如何将_children强制转换为未指定的 Container 类,以便我可以访问其toString函数。

如果我使用上述方法,则在链接时出现错误:

undefined reference to Container<void*>::toString()
undefined reference to Container<bool*>::toString()

以及我曾经使用过的所有其他类型。但是,我想避免专门化所有可能的类型。

编辑: 正如建议将容器的内容.cpp移动到头文件: 如果我这样做,我会收到这样的错误:

Multiple definition of Container<int>::toString().
First defined here

似乎基本上,无论我包括在哪里Container.h我都会得到如此多重的定义。这虽然我有一个

#ifndef CONTAINER
#define CONTAINER

包括守卫?

C++模板仅在替换时编译。

在您的情况下,Container<T>::toString在 sidecontainer.cpp中定义,但没有替换,因此不会编译它们。

当你引用Container<T>::toString某处时,函数的定义对编译单元不可见,编译将生成一个重定位槽,希望在链接阶段找到定义。但是该函数从未在任何地方定义过,因此您遇到了链接错误。

解决方案:将函数定义放在头文件中。

这里有一些更详细的解释。