我有一个奇怪的问题。我想实现类似于(https://stackoverflow.com/a/582456/3449968)的东西来按名称检索C ++对象。但我的对象使用模板。所以这是我的修改:
template <int dim>
class AspenFunction: public Function <dim>
{
// define the type of the map to handle all functions
typedef std::map<std::string, AspenFunction<dim>*(*)()> map_type;
static AspenFunction * create_aspen_function (const std::string& s)
{
typename map_type::iterator it = getMap()->find(s);
AssertThrow(it == getMap()->end(), ExcMessage("The aspen_function name '" + s + "' is not registered."));
return it->second();
}
protected:
static map_type * getMap()
{
if (!_map)
_map = new map_type;
return _map;
}
private:
static map_type * _map;
};
template <typename T, int dim>
AspenFunction<dim> * createT() { return new T; }
template <typename T, int dim>
class Registrar: AspenFunction <dim>
{
public:
Registrar(const std::string& s)
{
AspenFunction<dim>::getMap()->insert(std::make_pair(s, &createT<T, dim>));
}
};
template class AspenFunction<2>;
编译时,我得到了
Linking CXX executable nssolver
Undefined symbols for architecture x86_64:
"AspenFunction<2>::_map", referenced from:
AspenFunction<2>::getMap() in main.cc.o
所以,我尝试通过添加以下内容来实例化_map
:
template <> AspenFunction<2>::map_type * AspenFunction<2>::_map;
但是我收到以下错误:
/include/equation_handler.h:94:62: error: explicit specialization of '_map' after instantiation
template <> AspenFunction<2>::map_type * AspenFunction<2>::_map;
^
/include/equation_handler.h:69:14: note: implicit instantiation first required here
if (!_map)
^
我不知道还能做什么。我错过了什么吗?
我使用以下编译器
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
答案 0 :(得分:2)
您只是声明了static
数据成员_map
,它缺少定义。在类定义之后立即添加定义(最好)。
template <int dim>
typename AspenFunction<dim>::map_type *AspenFunction<dim>::_map;
但是,我完全取消了数据成员并将getMap()
功能更改为
static map_type& getMap()
{
static map_type instance;
return instance;
}
instance
对象将在第一次调用getMap()
时创建,而C ++ 11保证实例化是线程安全的。