【发布时间】:2013-11-11 18:16:57
【问题描述】:
首先,如果我的术语有些不准确或不正确,我深表歉意:这是 C++ 的一个方面,我没有过多处理。
我正在为一个 iOS 项目使用 Google 的 sparsehash 哈希表实现(我正在处理共享库,因为它针对越狱设备):特别是,我正在使用 dense_hash_map:我需要该模板的对象(命名正确吗?)作为结构的成员,该结构在项目中的多个文件之间共享。
我需要在__attribute__((constructor)) 函数(共享库的构造函数)中访问那个“对象”(即结构内的dense_hash_map)。问题显然是,模板的“自动构造函数”在 dyld 处理共享库的构造函数之后被调用:我只能在手动调用构造函数时使用dense_hash_map 对象就像在 __attribute__((constructor)) 函数中的 mymap = dense_hash_map<const char*, int, hash<const char*>, eqstr>(); 一样。
但是,模板构造函数以这种方式被调用了两次,一次是手动调用,一次是根据 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;
}
【问题讨论】:
-
你能分享无法编译的示例代码吗?
-
我遇到的唯一可能与编译有关的问题是如何声明模板对象,而无需通过其构造函数对其进行初始化。我没有任何不能编译的代码。
标签: c++ templates constructor