1

我有一个 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 不支持这种类型的大初始化?此外,在编译时是否有针对已知值进行如此大的初始化的设计模式?

4

2 回答 2

2

使用一个数组,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 字符串进行测试)。

于 2017-08-22T11:50:31.720 回答
1

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

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

如:

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"
于 2017-08-22T11:43:59.150 回答