5

例如:

InitEmployee()
{
    vector<Employee> employeeList = {
        Employee("Clark Kent",0),
        Employee("Bruce Wayne",1),
        ...
        Employee("Hal Jordan",65535)
    }
}

我无法从文件或数据库中查询,因为该程序需要位于单个可执行文件中,因此必须对所有常量数据进行硬编码。我实际上使用 boost 的 multi_index_container 按名称和 id 进行快速查找,但为了简单起见,我在这里使用向量作为示例。问题是我不能在没有堆栈溢出的情况下在单个函数中拥有那么多 (2^16) 常量数据。有没有更好的方法来初始化这个列表而不拆分函数?

我正在使用VC12。谢谢!

更新

查看选择的答案。正如其他人提到的那样,使用静态将迫使它继续数据而不是堆栈。这就是我最终的结果:

InitEmployee()
{
    static Employee employeeList[] = {
        {"Clark Kent",0},
        {"Bruce Wayne",1},
        ...
        {"Hal Jordan",65535}
    }

    vector<Employee*> employeeVec;
    int count = sizeof(employeeList) / sizeof(Employee);
    for (int i = 0; i < count; i++)
    {
        employeeVec.emplace(&employeeList[i]);
    }
}

问题是 Employee 类使用了一个字符串类而不是 c-string,所以我不想在内存中复制它的两个副本。这样我最终得到的只是指针的额外内存,这仍然很多,但我相信这是最好的选择!也适用于 multi_index_container!谢谢

4

4 回答 4

5

Use a static array to store the initialization data.

InitEmployee()
{
    static char const* const names[] = {
        "Clark Kent",
        "Bruce Wayne",
        ...
        "Hal Jordan"
    };

    size_t const n = sizeof(names) / sizeof(*names);

    vector<Employee> employeeList;
    employeeList.reserve(n);
    for (size_t i=0; i<n; ++i)
        employeeList.emplace_back(names[i],i);
    ...
}
于 2014-04-01T20:36:48.457 回答
0

有两种选择浮现在脑海中。第一个取决于 Visual Studio 的版本。您使用的是 Visual Studio 2012 还是 12.0 版(令人困惑的是,VS2012 实际上是 11.0)。如果您使用的是 2013(即 12.0),那么您可以选择使用 C++11 中新的初始化列表(例如,请参阅常见问题解答

vector<Employee> employeeList = {
    {"Clark Kent",0},
    {"Bruce Wayne",1},
    ...
    {"Hal Jordan",65535}
};

初始化列表依赖于 C++11 右值移动语义,以确保您在应用程序中只得到一份数据副本。

另一种选择是使用boost::assign(请参阅文档),这意味着您可以使用相同类型的语法,但动态进行分配:

#include <boost/assign/std/vector.hpp> // for 'operator+=()'
using namespace boost::assign; // bring operator+= into scope
vector<Employee> employeeList;
employeeList += Employee("Clark Kent", 0),
                Employee("Bruce Wayne", 1), ...
于 2014-04-01T21:14:48.237 回答
0

由于您说您使用的是 VC 12,并且您有一个可执行文件(并且没有数据文件),因此将硬编码数据放在资源中,而不是程序代码中。

适合的资源是 RCDATA 类型。 http://msdn.microsoft.com/en-us/library/windows/desktop/aa381039(v=vs.85).aspx

于 2014-04-01T20:47:46.780 回答
0

您确定过多的字符串文字会导致堆栈溢出吗?即使他们愿意,您也可以尝试将它们放在全局范围内:

const char *data = R"(
Clark Kent,0
Bruce Wayne,1
...
Hal Jordan,65535)"

/* ... */

int main()
{
    /* ... */
}

如果它可以用巨大的字符串文字很好地编译,你甚至可以尝试使用来自某个 DB 文件而不是列表的原始数据。

于 2014-04-01T20:40:24.340 回答