在模板类中初始化C++静态常量数组

7

我有以下模板类:

template <unsigned N>
class XArray {
  static const int Xdata[N];
};

我想要为我使用的每个XArray<N>初始化静态常量数组,例如让XArray<N>::Xdata = {1, 2, 3, ..., N}。如何实现?


这个链接应该会有所帮助。 - bibbsey
看起来“数组”是一个不错的解决方案,谢谢。 - Oliver Q
3个回答

4

你在类中声明了一个静态常量整型数组,所以你必须在类声明之外定义这个静态成员,就像这样:

template<unsigned N>
class XArray
{
public:
static const int array[N];
};
template<unsigned N>
const int XArray<N>::array[N] = {1,2,3,4,5};

但是有一件事需要注意:当您使用此模板时,必须确保“N”大于您初始化数组的数量。


但是我们可以使用constexpr函数来初始化静态数组,并填充从1到N的完整数字序列吗? - alexbuisson
我不这么认为。因为当你声明一个const成员时,你必须给它一个初始化的值,如果你想要初始化一个const静态数组的每个元素,你必须使用const_cast将const元素更改为普通元素。 - minicaptain

2

编辑:

看起来有人已经在其他问题中提供了你的问题的解决方案,而且答案与我的相同。

此外,要获取更通用的答案,可以查看此问题的答案。


代码

如果您不介意使用C++11功能,则可变模板可能会很方便:

template <unsigned ...Args>
struct XArrayData
{
    static const int Values[sizeof...(Args)];
};

template<unsigned N, unsigned ...Args>
struct _XArrayGenerator
{
    typedef typename _XArrayGenerator<N - 1, N, Args...>::Xdata Xdata;
};

template<unsigned ...Args>
struct _XArrayGenerator<1, Args...>
{
    typedef typename XArrayData<1, Args...> Xdata;
};

template<unsigned N>
struct XArray
{
    typedef typename _XArrayGenerator<N>::Xdata Xdata;
};

template <unsigned ...Args>
const int XArrayData<Args...>::Values[sizeof...(Args)] = { Args... };

说明

XArray 模板结构以数组元素数量作为模板参数 (N)。在编译时,它使用 _XArrayGenerator 生成具有 N 个连续数字的模板参数列表。它从数字 N 开始,然后递归地使用自身,直到达到 1。此时,模板参数列表如下:

1, 2, ..., N

最后一件事是将这些参数传递给 XArrayData。代码的最后一行(实际数组的定义)使用这些参数来初始化数组。

用法

for (int i = 0; i < 3; ++i)
    cout << XArray<3>::Xdata::Values[i] << endl;

输出:

1
2
3

0
您可以按如下所示进行初始化。请参阅内联注释以获取我的说明。
template <unsigned N>
class XArray {
    private:
        static const int Xdata[N];
    public:
        //I added this for illustration purpose
        void print()
        {
            for (int i = 0; i < N; ++i)
            {
                std::cout << Xdata[i] << std::endl;
            }
        }
};

//you can initialize like this
//automatic size counting works with static arrays
//here I initialize with 3 elements
//make sure you don't use N < 3 anywhere
template <unsigned N>
const int XArray<N>::Xdata[] = {1,2,3};

int main(void)
{
    XArray<3> obj1; //N = 3: This is okay.
    XArray<8> obj2; //N > 3: This is okay. Remaining elements will be 0.
    XArray<2> obj3; //N < 3: This is also okay.
    obj1.print();
    obj2.print();
    obj3.print(); //but this will give compilation error

    return 0;
}

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