在模板类中初始化C++数组成员

3
我需要实现一个安全的数组类,控制访问底层C数组时的索引:
template <typename T, int N> class SafeArray
{
public:
    T &operator[](int index)
    {
        assert(0 <= index && index < N);
        return m_data[index];
    }
private:
    T m_data[N];
};

现在我写的是SafeArray<bool, 3> a;,而不是bool a[3];

如何支持数组初始化,例如bool b[3] = {false};?我的意思是,在构造SafeArray<bool, 3> b;之后,我应该做什么才能得到b.m_data[] = {false, false, false}

我想我应该向SafeArray添加一个构造函数,但是那个构造函数的具体内容是什么呢?模板参数T可以是任何类型,不一定是bool。我正在使用C++11之前的版本。


std::initializer_list<T>。查看我的一个问题:https://dev59.com/A2Qn5IYBdhLWcg3w7a2K - Koushik Shetty
1
你想重新实现std::array<>吗?你可以直接使用它,或者通过阅读源代码来学习。 - Balog Pal
在C++11之前,我认为你可以通过为每个长度准备初始化模板来实现某些功能。长度为2的初始化模板将使用长度为1的初始化模板再加上一个。可能在Alexandrescu的《现代C++设计》中提到过。 - Afriza N. Arief
@Nick 和 ForEveR,抱歉我没看到那个。 - Koushik Shetty
你如何安全地执行 T m_data[N]? - Ariel Pinchover
显示剩余3条评论
3个回答

2
我是指在构造SafeArray<bool, 3> b;后,如何使b.m_data[] = {false, false, false}?如果我理解你的问题正确,那么你只需要编写一个默认构造函数来初始化数组即可:
SafeArray() : m_data()
{
}

完整代码如下:
template <typename T, int N> class SafeArray
{
public:
    SafeArray() : m_data()
    {
    }
    T &operator[](int index)
    {
        assert(0 <= index && index < N);
        return m_data[index];
    }
private:
    T m_data[N];
};

这里有一个实时示例


1
不是SafeArray() : m_data() {}这样的技巧,就可以避免调用std::fill吗? - juanchopanza
@juanchopanza:哎呀!是的,你说得对。我要去编辑,谢谢。 - Andy Prowl

0

由于您正在使用C++03(因此没有std :: array),我更愿意推荐您使用boost :: array,它基本上是std :: array的C++03实现。 (实际上,std :: array受到boost :: array的启发)。

否则,将您的类设置为聚合体,即(根据C++03 8.5.1 / 1)

聚合体是一个数组或类(第9条款),没有用户声明的构造函数,没有私有保护非静态数据成员(第11条款),没有基类(第10条款)和没有虚拟函数。

然后,您的类将支持按您要求进行聚合初始化。

更新:再次阅读OP(和{{link1:Andy Prowl}}的{{link2:answer}}),我不确定我是否理解问题。我在这里提出的是一种在构建时初始化SafeArray的方法,例如,

SafeArray<bool, 3> b = { false, false, false };

我也考虑过这个问题,但我认为原帖作者想要保证安全访问,所以他们需要将数组数据成员保持私有 - 这使得该类成为非聚合体。 - Andy Prowl

0

那么呢...?

SafeArray() {
    for (int i = 0; i < N; ++i) {
        m_data[i] = T();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接