类模板的成员函数的专业化

时间:2018-08-10 08:33:03

标签: c++ templates

我有一个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类,以便我可以访问其{{1 }}功能。

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

toString

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

编辑: 有人建议将container.cpp的内容移动到头文件中:如果执行此操作,则会出现如下错误:

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

基本上,无论我包括Multiple definition of Container<int>::toString(). First defined here 哪里,我都会得到如此多重的定义。尽管我有一个

Container.h

包括警卫?

1 个答案:

答案 0 :(得分:1)

在C ++模板中,仅当替换时才编译。

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

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

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

Here是一些更详细的说明。