gpt4 book ai didi

c++ - 是否可以在静态编译时从不同的源文件构建一个 vector ?

转载 作者:行者123 更新时间:2023-11-28 03:04:57 27 4
gpt4 key购买 nike

我想在 jniOnLoad 方法中缓存 jni 类 ID。最终这个过程将按如下方式进行:

for each class name in my list, call env->FindClass

作为一名开发人员,我宁愿不必将类名添加到位于我的类之外的中央静态 vector 。相反,我想在我正在编辑的文件中继续注册这个集合。例如

JNIUtility.h
void appendClassName(std::string &className); // append name to mClassNameVector

JNIUtility.cpp
vector<string> mClassNameVector;
void jniOnLoad()
// iterate over all items in mClassNameVector and obtain the class id's

...

NewClass.cpp
appendClassName("com/my/path/NewClass");

我的问题是,我可以在静态编译时 push_back 到 mClassNameVector 吗?如果是,怎么办?

最佳答案

你不能构建你的 std::vector<std::string>在编译或链接时。但是,您可以在静态初始化期间构建它。您可以让一个全局对象的构造函数调用另一个全局对象上的某些东西。例如,您可以这样做:

std::vector<std::string> mClassNameVector;
static bool dummy = []{ mClassNameVector.push_back("some string"); return true; };

但是,一旦将注册移动到不同的翻译单元,就会出现两个问题:

  1. 全局对象的构造顺序在翻译单元之间是不确定的(在翻译单元内,它只是从上到下)。避免调用 push_back() 时出现问题在尚未构建的 vector 上,您只需将对象包装到一个函数中:

    std::vector<std::string>& mClassNameVector() {
    static std::vector<std::string> rc;
    return rc;
    }
    static bool dummy = []{ mClassNameVector().push_back("some string"); return true; };

    static函数局部变量是在第一次调用函数时构造的,这种方法保证了mClassNameVector()在访问之前构建。请注意,该构造在 C++03 中不是线程安全的。但是,它在 C++ 中是线程安全的(截至 2011 年修订版):只有一个线程会初始化 rc . rc 时进入函数的任何其他线程正在 build 中将阻塞。

  2. 另一个潜在的问题是您的类可能无法从任何地方引用,因此包含注册变量的文件可能不会包含在最终的可执行文件中。特别是在库中实现类并希望它们注册自己时往往会失败。此外,当目标文件以将不同实体放入不同部分的方式构建时,注册变量有可能未链接到可执行文件中。但是,通常情况下,它会显式链接目标文件。除非每个文件都包含从某处引用的符号,否则将目标文件放入库通常是行不通的。

关于c++ - 是否可以在静态编译时从不同的源文件构建一个 vector ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19967439/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com