【发布时间】:2014-12-30 00:37:26
【问题描述】:
对不起,如果标题令人困惑,我找不到一个简单的方法来用一个简单的句子来写它。无论如何,我面临的问题:
// header:
class SomeThing
{
private:
SomeThing() {} // <- so users of this class can't come up
// with non-initialized instances, but
// but the implementation can.
int some_data; // <- a few bytes of memory, the default
// constructor SomeThing() doesn't initialize it
public:
SomeThing(blablabla ctor arguments);
static SomeThing getThatThing(blablabla arguments);
static void generateLookupTables();
private:
// declarations of lookup tables
static std::array<SomeThing, 64> lookup_table_0;
static SomeThing lookup_table_1[64];
};
getThatThing 函数旨在从查找表中返回一个实例。
// in the implementation file - definitions of lookup tables
std::array<SomeThing, 64> SomeThing::lookup_table_0; // error
SomeThing Something::lookup_table_1[64]; // <- works fine
我不能使用Something 的std::array,除非我在课堂上添加一个公共ctor SomeThing()。它适用于旧式数组,我可以定义数组,并将其填充到 SomeThing::generateLookupTables() 函数中。显然std::array<SomeThing, 64> 类型没有构造函数。关于如何使其发挥作用的任何想法,或者可能为这个概念提供更好的结构?
============= 编辑 =======
friend std::array<SomeThing, 64> 方法似乎是个好主意,但是:
它也将用于其他地方的数组中。我想保证这个类总是对外部用户保持某些不变量。使用这个友好的数组,用户可能会意外创建一个未初始化的 SomeThing 数组。
此外,查找表是使用相当复杂的过程生成的,不能按内联方式完成,如std::array<SomeThing, 64> SomeThing::lookup_table_0(some value)
【问题讨论】:
-
如果您的课程是可移动的,请考虑使用
std::vector。如果它不是可移动的,我认为std::deque仍然可以工作,当然前提是你就位。 -
我想知道这个类定义是否格式错误,标准容器应该只用完整类型实例化。 (而且这个问题只是由于类包含来自自身模板的静态成员)
-
Matt:该标准容器尚未在标头中实例化,而仅在实现中。
-
这个问题很有趣,因为它是 C 样式数组不能简单地替换为
std::array -
我想我还有另一个半解决方案:如果 C++ 在这方面的工作方式与 C 相同,则全局变量,例如Something::lookup_table_0(它不在任何函数的堆栈中,所以是全局的) 被初始化为清零内存。因此,如果我创建一个仅将
some_data设置为零的私有构造函数,并使用它对 std::array 进行值初始化,这本质上是相同的。但它仍然是一个 hack。
标签: c++ c++11 initialization static-initialization stdarray