简体   繁体   English

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

[英]Specialization of member function of class template

I have a Base class which I use as a Tree. 我有一个用作树的Base类。 From this Base class I derived a template Container class which should be able to hold various types. 从这个基类中,我派生了一个模板Container类,该类应该能够容纳各种类型。 I would like to give the Container class a toString function, which converts its values and the values of all of its children to a string. 我想给Container类一个toString函数,该函数将其值及其所有子级的值转换为字符串。 A Container<A> can have a child of a different type Container<B> . Container<A>可以具有另一个类型Container<B>

I don't know how to do this. 我不知道该怎么做。 Below is my code. 下面是我的代码。

// File base.h:
class Base {
    public:
    virtual string toString();
    protected:
        vector<Base *> _children
}

// File base.cpp:
string Base::toString() {
    string a="something"
    return a;
}

Then I have a templated derived class: 然后,我有一个模板化的派生类:

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

I would like to specialize the toString function, so it can deal with different types: 我想专门研究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;
}

I gave the Base class also a toString function, as I don't know how I would cast the _children to an unspecified Container class so I can access its toString function. 我还给Base类提供了toString函数,因为我不知道如何将_children转换为未指定的Container类,以便可以访问其toString函数。

If I use the above approach, I get an error at linking: 如果使用上述方法,则在链接时会出现错误:

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

and for all the other types I ever used. 以及我曾经使用过的所有其他类型。 However, I would like to avoid specializing all possible types. 但是,我想避免专门化所有可能的类型。

Edit: As it has been suggested to move the content of container.cpp to the header file: If I do this, I get errors like this: 编辑:由于建议将container.cpp的内容移动到头文件中:如果执行此操作,则会出现如下错误:

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

It seems basically that whereever I include Container.h I get such a multiple definition. 基本上,无论我在哪里包含Container.h我都会得到这样的多重定义。 This although I have a 尽管我有一个

#ifndef CONTAINER
#define CONTAINER

include guard? 包括警卫?

In C++ template only compiles when substituted. 在C ++模板中,仅在替换时才编译。

In your situation, Container<T>::toString are defined in side container.cpp , but no substituted, so they won't be compiled. 在您的情况下, Container<T>::toString是在端container.cpp中定义的,但没有替代值,因此它们将不会被编译。

When you reference to Container<T>::toString somewhere, the definition of the function is not visible to the compile unit, the compile will generate a relocation slot, hoping the definition will be find at link stage. 当您在某处引用Container<T>::toString ,该函数的定义对于编译单元不可见,编译将生成一个重定位槽,希望在链接阶段找到该定义。 But the function is never defined anywhere, so you got link error. 但是该函数从未在任何地方定义,因此您遇到了链接错误。

Solution: put the function definition to header file. 解决方案:将函数定义放在头文件中。

Here are some more detailed explanation. 是一些更详细的说明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM