C ++模板静态地图初始化

时间:2013-12-03 06:38:49

标签: c++ templates static initialization

我得到的错误是undefined reference,我意识到我在头文件中声明的静态变量需要初始化。这已在下面的实现文件中完成,但错误仍然存​​在。如果我将初始化移动到头文件,它将编译但在运行时由于某种原因我得到一个错误的访问错误。 (注意:我声明的s_testmap用于测试)

标题

class Context;
class AttributeSet;

template <typename BaseT, typename SubT = BaseT> // SubT must be-a BaseT.
struct object_factory {
    typedef BaseT result_type;
    typedef SubT actual_type;
    static result_type * new_instance(Context *context, AttributeSet *attrs) { return new actual_type(context, attrs); }
    static result_type * no_instance() { return 0; } // explained below
};

template <typename BaseType, typename KeyType = std::string>
class instantiator {

public:

    typedef BaseType value_type; // base-most type
    typedef KeyType key_type; // lookup key type
    typedef value_type *(*factory_type) (androidcpp::Context *context, androidcpp::AttributeSet *attrs); // factory function signature
    typedef std::map<key_type, factory_type> object_factory_map; // key-to-factory map

    // Uses a mapped factory to return a new value_type object
    // polymorphically:
    static value_type* instantiate(const key_type &key, androidcpp::Context *context, androidcpp::AttributeSet *attrs) {

        typename object_factory_map::const_iterator it = s_factoryMap.find(key);
        typename std::map<std::string, int>::const_iterator it1 = s_testmap.find(key);

        bool found = it1 != s_testmap.end();

        if (it != s_factoryMap.end()) {
            return (it->second)(context, attrs); // run our factory.
        }

        return 0; // no factory found :(
    }

    // Maps the given BaseType factory with the given key.
    // You may pass a factory which returns a subtype, but the
    // default factory will always return an actual value_type object
    // (assuming value_type is not abstract, in which case it returns
    // 0).
    // Note that by providing a default factory here we make a trade-off:
    // this code will not compile when value_type is abstract. If we
    // force the user to specify a factory we can support abstract types,
    // but we almost double the amount of code needed to register types,
    // as demonstrated later. Later in this paper we will mention a cleaner
    // solution which allows us to keep the default argument here and support
    // abstract types.
    static void register_factory(const key_type &key, factory_type fp = 0) {

        if (!fp) fp = object_factory<value_type>::new_instance;

        s_testmap.insert(std::make_pair(key, 1));
        s_factoryMap.insert(std::make_pair(key, fp));
    }

    // Registers a factory for a subtype of base_type.
    // This is the same as calling register_factory( key, mySubTypeFactory ),
    // except that it installs a default factory returning a SubOfBaseType
    // if the client does not provide one. SubOfBaseType must be a publically
    // accessible ancestor of base_type, or must be base_type.
    // Please see the notes in register_factory() regarding the second
    // parameter: the same notes apply here.
    template <typename SubOfBaseType>
    static void register_subtype(const key_type &key, factory_type fp = 0) {

        if (!fp) fp = object_factory<value_type, SubOfBaseType>::new_instance;

        register_factory(key, fp);
    }

    // Tells us if a given key is registered with a base_type
    // factory. Only rarely useful, but here it is...
    static bool is_registered(const key_type &key) {
        return s_factoryMap.end() != s_factoryMap.find(key);
    }

private:

    static object_factory_map s_factoryMap;
    static std::map<std::string, int> s_testmap;
};

template <typename BaseType, typename KeyType>
typename instantiator<BaseType, KeyType>::object_factory_map instantiator<BaseType, KeyType>::s_factoryMap = instantiator<BaseType, KeyType>::object_factory_map();

实施

template <typename BaseType, typename KeyType>
std::map<std::string, int> instantiator<BaseType, KeyType>::s_testmap = std::map<std::string, int>({
    {"test", 1}
});

1 个答案:

答案 0 :(得分:0)

由于在静态地图初始化之前访问了静态函数,因此导致该问题。我最后改变这个类没有静态方法,但是成为一个单身人士,它最终解决了我的问题。