I have a strange problem. I want to implement something similar to (https://stackoverflow.com/a/582456/3449968) to retrieve C++ object by name. But my objects use templates. So this is my modification:
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>;
When compiled, I get
Linking CXX executable nssolver
Undefined symbols for architecture x86_64:
"AspenFunction<2>::_map", referenced from:
AspenFunction<2>::getMap() in main.cc.o
So, I tried to instantiate _map
by adding the following:
template <> AspenFunction<2>::map_type * AspenFunction<2>::_map;
But I get the following error:
/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)
^
I don't know what else to do. Am I missing something?
I'm using the following compiler
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix