首先,如果我的术语有些不准确或不正确,我深表歉意:这是 C++ 的一个方面,我没有过多地处理。
我正在为 iOS 项目使用 Google 的 sparsehash 哈希表实现(我正在处理共享库,因为它针对越狱设备):特别是,我正在使用dense_hash_map
:我需要该模板的对象(命名正确吗?)作为在项目中的多个文件之间共享的结构的成员。
我需要在一个函数内访问那个“对象”(即结构内的dense_hash_map)__attribute__((constructor))
,一个共享库的构造函数。问题显然是,模板的“自动构造函数”在 dyld 处理共享库的构造函数之后被调用:只有在函数内部dense_hash_map
手动调用构造函数时,我才能使用该对象。mymap = dense_hash_map<const char*, int, hash<const char*>, eqstr>();
__attribute__((constructor))
但是,模板构造函数以这种方式被调用了两次,一次是手动调用,一次是根据 C++ 自动构造函数调用。如何在不改变模板本身设计的情况下避免这种情况?
其他奇怪的事情是:
- 如果该
dense_hash_map
对象在该函数内被声明为局部变量,则一切正常。 - 该问题仅发生在共享库中:简单的独立程序不受此问题的影响。
所以,最后,我想问的是:
- 如何声明一个模板对象并强制它手动初始化,基本上没有模板构造函数被自动调用?
- 模板构造函数在局部/全局变量情况下的处理方式有何不同?
如果我没有使用正确的术语,请告诉我。我希望有人可以阐明这一点,在此先感谢!
更新:不同情况的示例代码。
// global dense_hash_map
dense_hash_map<const char*, int, hash<const char*>, eqstr> months;
__attribute__((constructor)) static void my_constructor_0()
{
/*
actually crashes because you need to call set_empty_key()
right after the template constructor, which has not been called
yet, at this point
*/
months.set_empty_key(NULL);
months["january"] = 31;
}
__attribute__((constructor)) static void my_constructor_1()
{
// local dense_hash_map
dense_hash_map<const char*, int, hash<const char*>, eqstr> months;
/*
doesn't crash, works as it should and the map is being initialized
correctly
*/
months.set_empty_key(NULL);
months["january"] = 31;
}
// global dense_hash_map
dense_hash_map<const char*, int, hash<const char*>, eqstr> months;
__attribute__((constructor)) static void my_constructor_2()
{
/*
works as it should but if you add a log to the template constructor,
you see it being initialized twice: the first one is the manual call
and the second one is the automatic constructor
*/
months = dense_hash_map<const char*, int, hash<const char*>, eqstr>();
months.set_empty_key(NULL);
months["january"] = 31;
}