【问题标题】:How to implement large vector initialization that compiles with gcc-4.4?如何实现用 gcc-4.4 编译的大向量初始化?
【发布时间】:2017-08-22 11:14:33
【问题描述】:

我有一个 20k 已知字符串的列表,我在编译时就知道并且永远不会改变。一种不可配置的字典。我不想在运行时从文件中加载它,因为这意味着很多不必要的架构:在某个路径中查找文件、指示路径的配置文件等。

我在 C++ 中想出了一个这样的解决方案:

在 a.cpp 中:

std::vector<std::string> dic;
dic.reserve(20000);
#define VECTOR_DIC_ dic;
#include values.inl
#undef VECTOR_DIC_

然后在 values.inl 中,包含 20k 个 push_back 调用的列表,如下所示:

VECTOR_DIC_.push_back("string1");
VECTOR_DIC_.push_back("string2");
...
VECTOR_DIC_.push_back("string20000");

此代码在 Debian 上与 gcc-4.8 一起编译并正常工作,但无法与 gcc-4.4 一起编译,gcc-4.4 永远无法完成对 a.cpp 文件的编译。

为什么 gcc-4.4 不支持这种大型初始化?另外,有没有一种设计模式可以在编译时对已知值进行如此大的初始化?

【问题讨论】:

  • 您应该将其存储为const char *S[],然后从S 构造dic - 这将允许您将dic 构造为const 向量,而无需依赖初始化功能。例如。 godbolt.org/g/REZdds
  • @JordiAdell 如果在编译时完成,我会感到惊讶......
  • @JordiAdell 即使有一个编译器可以做到这一点(我不这么认为)它也不是你可以依赖的可移植优化
  • std::vector 在其实现中依赖于动态分配,编译器几乎不可能在编译时解决这个问题。为此使用向量会浪费内存(无缘无故地将文字复制到动态分配的内存中)和时间;只需使用普通数组(或者,如果您真的需要向量,请将其设为 std::vector&lt;const char *&gt;,至少您不会复制字符串数据)。
  • ...或使用std::array&lt;const char*, N&gt;

标签: c++ gcc vector initialization gcc4.4


【解决方案1】:

使用const char * 的数组,然后从中初始化您的向量:

#include <string>
#include <vector>

char const * const S[] = {
    "string1",
    "string2"
};

const std::size_t N_STRINGS = sizeof(S) / sizeof(*S);

const std::vector<std::string> dic(S, S + N_STRINGS);

使用g++ 4.4.7 可以很好地编译(虽然没有使用 20k 字符串进行测试)。

【讨论】:

    【解决方案2】:

    编译器可能会因为初始化不在函数内部而犹豫不决。

    要使其工作,请将初始化程序插入函数中。

    如:

    std::vector<std::string> dic;  // wouldn't an std::set be a better match?
    
    bool InitDitionary() {
      dic.reserve(20000);
      #define VECTOR_DIC_ dic;
      #include values.inl
      #undef VECTOR_DIC_
      return true;
    }
    
    // you can then call InitDictionary at your discretion from within your app
    // or the following line will initialize before the call to main()
    bool bInit = InitDictionnary();
    

    或者,静态 const char* 替代方案也是可行的,您必须将字符串文件更改为这种格式,我建议您包含整个声明,因为它可能是由软件生成的。数组应该事先排序,所以你可以使用 binary_search、upper_bound 等搜索它......

    const char dic[20000] = {  // <-- optional, in the file, so you have the number of items 
        "string1",
        "string2",
        "string3",
        "string4",
        // ...
    };
    const size_t DIC_SIZE = sizeof(dic) / sizeof(dic[0]);  // :)
    

    您可以给文件一个 .cpp 扩展名,或包含为:

    #include "dictionary.inc"
    

    【讨论】:

      猜你喜欢
      • 2018-09-07
      • 2010-10-28
      • 2018-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多