模板方法的未定义参考错误
过去的一个半小时里,这让我疯狂。 我知道这是一件小事,但却找不到什么不对(事实上,星期五的下午,这个事实并没有帮助)。
我已经定义了下面的类,将保存从文件中读取的configuration参数,并让我从我的程序访问它们:
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
中定义为
template <typename T> T VAConfig::convert( const std::string& value ) { T t; std::istringstream iss( value, std::istringstream::in ); iss >> t; return t; }
一切都很简单。 但是,当我从我的主程序testing使用
int y = parameters->convert<int>("5");
我得到了undefined reference to 'int VAConfig::convert<int>...'
编译错误的undefined reference to 'int VAConfig::convert<int>...'
。 同上readParameter()
。
看了很多模板教程,但coul不知道这一点。 有任何想法吗?
模板化的代码实现不应该在.cpp
文件中:编译器必须在看到调用它们的代码的同时看到它们(除非使用显式实例化来生成模板对象代码,但即使如此.cpp
也是错误的文件types使用)。
你需要做的是将实现移动到头文件,或者如VAConfig.t.hpp
文件,然后#include "VAConfig.t.hpp"
每当你使用任何模板化的成员函数。
如果将模板化方法(convert和readParameter)的实现移动到头文件,它应该可以工作。
编译器必须能够访问模板化函数的实现。
模板方法仅仅是一个方法的模板。 模板参数将被填充到方法“实例化”的地方。
应该可以构build一个编译器,该编译器是模板方法声明的内容,并且有一个“模板编译”步骤来编译模板方法的所有需要的实例。
这不是微软的VC的情况。 不过,我听到一个同事在喃喃喃喃地说unix是这样的情况。
大多数编译器根据请求实例化模板方法,在源代码中使用它们。 为了实例化该方法,编译器必须“看见”模板函数体。 这就是为什么正文最经常放在头文件中,或者在例如.h.cpp文件中,然后将其作为.h文件的最后一行。