gpt4 book ai didi

c++ - 从独立的 TU 零碎地构建静态数据结构

转载 作者:行者123 更新时间:2023-11-28 02:15:13 27 4
gpt4 key购买 nike

我有几个独立编写的翻译单元;为了便于讨论,每个变量都有一个(静态或外部的)全局 std::string 变量。这些字符串可能有不同的名称,与 TU 的名称无关。而且我不保证编译的 TU 在与具有 main() 函数(例如,main.cpp)的 TU 链接之前会相互联系。它们都包含相同的头文件 magic1.h,它定义了一个名为 fun_strings 的全局变量,稍后我们将选择其类型。

现在,我希望能够执行以下操作:

#include <string>
#include "magic1.h"
int main() {
// magic2
for(const std::string& s : fun_strings) {
foo(s);
}
}

重点是即使 main.cpp_doesn't_include_any_of_the_other_TUs_,它们有一些静态代码导致 fun_strings 具有指向所有 TU 的单个字符串的拷贝/引用/指针。

当然,问题是如何实现这一点。我将“magic1”和“magic2”表示为可能放置通用代码的位置。对于带有字符串的示例 TU,将 foo.cppstd::string just_a_string("I 'm a foo fun string"); 某处。

注意事项:

  • 解决方案必须是线程安全的,尽管我猜这应该不是问题。
  • 这是我实际尝试做的事情的简化版本,对于动机有点模糊,我们深表歉意。
  • 忽略碰撞的可能性,在我遇到的实际问题中不可能有任何碰撞。
  • 我宁愿不做任何基于动态加载对象和遍历它们的符号表的事情(如果我使用静态方法失败,我可能会被简化为这样做)

最佳答案

创建一个在声明字符串时自动将字符串添加到 fun_strings 的类怎么样:

class fun_string
{
public:
fun_string(const char * string)
: m_string(string)
{
get_fun_strings().push_back(m_string);
}
private:
string m_string;
};

然后在翻译单元中,您将使用 fun_string 定义全局字符串。

在上面的代码中,我使用了 get_fun_strings() 而不是直接使用一个名为 fun_strings 的全局变量。这是为了避免任何 static initialisation fiasco在另一个静态变量的初始化中使用静态变量时可能出现的问题。

vector<string> & get_fun_strings()
{
static vector<string> v;
return v;
}

还要注意,从 C++11 开始,局部函数静态保证以线程安全的方式初始化。这可能不是什么大问题,因为如果您至少有一个全局 fun_string,函数局部静态将在 main() 之前初始化,并且因此很可能在创建任何其他线程之前。

至于忽略碰撞的要求——这可以在 fun_string 构造函数中完成。也就是说你应该在插入之前检查碰撞并适本地处理这种情况。

这是一个live demo这种方法。

一些注意事项:

  • 正如 Yakk 在评论中提到的,不要期望 get_fun_strings() 返回的 vector 包含 main() 之前的所有字符串。
  • 不要在静态对象的析构函数中使用get_fun_strings()。请参阅有关静态初始化顺序的页面了解其原因以及如何更改它以支持此类用法。

关于c++ - 从独立的 TU 零碎地构建静态数据结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34241034/

27 4 0
文章推荐: c++ - 无法使用 fstream 打开新的进出文件
文章推荐: c++ - 使用 fstream 读出 txt 文件崩溃 .exe
文章推荐: php - 为什么这个动态生成的
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com