[英]C++ Template Static Map 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}
});
由於在初始化靜態映射之前訪問了靜態函數,最終導致了該問題。 我最終將此類更改為不具有靜態方法,而是成為單例,最終解決了我的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.