关于c ++:模板方法的未定义引用错误

Undefined reference error for template method

本问题已经有最佳答案,请猛点这里访问。

在过去的一个半小时里,这让我很生气。我知道这是一件小事,但却找不到问题所在(当然,星期五下午多雨也无济于事)。

我定义了以下类,这些类将保存从文件中读取的配置参数,并允许我从程序中访问这些参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class VAConfig {
    friend std::ostream& operator<<( std::ostream& lhs, const VAConfig& rhs);

private:
    VAConfig();
    static std::string      configFilename;
    static VAConfig*        pConfigInstance;
    static TiXmlDocument*   pXmlDoc;
    std::map<std::string, std::string> valueHash;

public:
    static VAConfig* getInstance();
    static void setConfigFileName( std::string& filename ) { configFilename = filename; }
    virtual ~VAConfig();

    void readParameterSet( std::string parameterGroupName );
    template<typename T> T readParameter( const std::string parameterName );
    template<typename T> T convert( const std::string& value );
};

其中方法convert()VAConfig.cpp中定义为

1
2
3
4
5
6
7
8
template <typename T>
T VAConfig::convert( const std::string& value )
{
    T t;
    std::istringstream iss( value, std::istringstream::in );
    iss >> t;
    return t;
}

一切都很简单。但是当我从我的主程序测试

1
int y = parameters->convert<int>("5");

我得到一个undefined reference to 'int VAConfig::convert...'编译错误。同上,适用于readParameter()

看了很多模板教程,但没能搞清楚。有什么想法吗?


模板化代码实现不应该出现在.cpp文件中:编译器必须在看到调用它们的代码的同时看到它们(除非使用显式实例化生成模板化对象代码,但即使这样,.cpp也是错误的文件类型)。

您需要做的是在使用任何模板化成员函数时,将实现移动到头文件,或者移动到诸如VAConfig.t.hpp之类的文件,然后移动到#include"VAConfig.t.hpp"之类的文件。


如果将模板化方法(convert和readparameter)的实现移到头文件中,它应该可以工作。

编译器必须能够访问模板化函数在其实例化点的实现。


模板方法只是…方法的模板。模板参数将在"实例化"方法的位置填写。

应该可以构建一个满足模板方法声明的编译器,并让"模板编译"步骤编译模板方法所需的所有实例。

微软的风投并非如此。不过,我听到一位同事在抱怨Unix上的情况。

大多数编译器根据请求实例化模板方法,在源代码中使用这些方法。为了实例化该方法,编译器必须"看到"模板函数体。这就是为什么正文通常放在头文件中,或者放在例如.h.cpp文件中,然后作为.h文件的最后一行包含在其中。