C++ C++;:根据模板参数填充数组

C++ C++;:根据模板参数填充数组,c++,templates,arrays,fill,C++,Templates,Arrays,Fill,基本上,情况如下: 我有一个类模板(使用类型为int的一个模板参数length),希望引入一个静态数组。此数组的长度应为length,并包含1到length的元素 到目前为止,代码如下所示: template<int length> class myClass{ static int array[length]; }; 模板 类myClass{ 静态整数数组[长度]; }; 然后我想写一行代码初始化数组 // of course, the line below does

基本上,情况如下:

我有一个类模板(使用类型为
int
的一个模板参数
length
),希望引入一个静态数组。此数组的长度应为
length
,并包含
1
length
的元素

到目前为止,代码如下所示:

template<int length>
class myClass{
    static int array[length];
};
模板
类myClass{
静态整数数组[长度];
};
然后我想写一行代码初始化数组

// of course, the line below does not work as intended.
template<int length> int myClass<length>::array[length]={1,2, ..., length};
//当然,下面这行并没有按预期的那样工作。
模板int myClass::数组[length]={1,2,…,length};
(如何)实现这一点?

使用“静态构造函数”习惯用法

//编辑2

#include <iostream>

template<int length>
class myClass {
public:
    typedef int ArrayType[length];

    static struct StaticData {
        ArrayType array;

        StaticData()
        {
            for (int i = 0; i < length; i++) array[i] = i;
        }
    }
    static_data;

    static ArrayType &array;
};

template<int length>
typename myClass<length>::StaticData myClass<length>::static_data;

template<int length>
typename myClass<length>::ArrayType &myClass<length>::array = myClass<length>::static_data.array;

int main(int argc, char** argv) {
    const int LEN = 5;
    for (int i = 0; i < LEN; i++) {
        std::cout << myClass<LEN>::array[i];
    }
}
#包括
模板
类myClass{
公众:
typedef int ArrayType[长度];
静态结构静态数据{
数组类型数组;
静态数据()
{
对于(int i=0;istd::cout不能用C样式的数组实现这一点,因为它们没有值语义


但是,如果您使用类似于
std::tr1::array
的东西,那么您可以通过初始化函数结果或使用生成这些值的迭代器轻松完成所需的操作。

您可以编写一个包装类,但我确信有更干净的解决方案:

template <size_t length>
class array_init_1_to_n
{
    int array[length];

public:

    array_init_1_to_n()
    {
        for (int i = 0; i < length; ++i)
        {
            array[i] = i + 1;
        }
    }

    operator int*()
    {
        return array;
    }

    operator const int*() const
    {
        return array;
    }
};

template<size_t length>
class myClass{
    static array_init_1_to_n<length> array;
};
模板
类数组\u init\u 1到\u n
{
整数数组[长度];
公众:
数组_init_1_to_n()
{
对于(int i=0;i
将for循环嵌入到一个最大长度的循环中,其基本上与使用初始值设定项相同:

for(int i = 0; i < length; i++)
    array[i] = i + 1;
for(int i=0;i
这似乎很难。我能想到的最接近的方法是:

template<int length>
class myClass
{
  public:
    myClass()
    {
      static InitializeArray<length> initializeArray(&array);
    }
    template<int length>
    class InitializeArray
    {
    public:
      InitializeArray(int* array) 
      {
        for(int i = 0; i < length ; ++i)
        array[i] = i;
      }
    };
    static int array[length];
    static myClass instance;
};
template<int length> int myClass<length>::array[length];
template<int length> myClass myClass::instance;
模板
类myClass
{
公众:
myClass()
{
静态initializerRay initializerRay(&array);
}
模板
类初始化数组
{
公众:
InitializeArray(int*数组)
{
对于(int i=0;i
以下是使用Boost.MPL的示例:

#include <cstddef>
#include <iostream>

#include <boost/mpl/range_c.hpp>
#include <boost/mpl/string.hpp>

template<std::size_t length>
struct myClass {
  static const std::size_t Length = length;
  typedef typename boost::mpl::c_str< boost::mpl::range_c<std::size_t, 1, length + 1> > Array;
};

int main() {
  // check whether the array really contains the indented values
  typedef myClass<10> test;
  for (std::size_t i = 0; i < test::Length; ++i) {
    std::cout << test::Array::value[i] << std::endl;
  }
}
#包括
#包括
#包括
#包括
模板
结构myClass{
静态常数std::size\u t Length=长度;
typedef typename boost::mpl::c_str数组;
};
int main(){
//检查数组是否确实包含缩进值
typedef-myClass测试;
对于(标准::尺寸\u t i=0;istd::cout您可以使用额外静态成员的显式模板实例化,该静态成员的构造函数负责填写条目:

template<int length>
class myClass{
public:
    static int array[length];

    typedef enum{LENGTH=length} size_;

    struct filler
    {
        filler(void)
        {
            for(int i=0;i<LENGTH;++i)
                array[i]=i+1;
        }
    };

    static filler fill_;
};

// of course, the line[s] below now do work as intended.
template<int length> 
int myClass<length>::array[length];

//static member definition
template<int length>
typename myClass<length>::filler myClass<length>::fill_;

//explicit template instantiation
template myClass<5>::filler myClass<5>::fill_;

int main(void)
{
    for(int i=0;i<myClass<5>::LENGTH;++i)
        cout<<myClass<5>::array[i]<<endl;

    return 0;
}
模板
类myClass{
公众:
静态整数数组[长度];
typedef枚举{LENGTH=LENGTH}size\;
结构填充
{
填料(空隙)
{

对于(int i=0;i你不能将数组包装成一个静态函数,例如

template<int length>
class myClass {
    static int* myArray() {
        static bool initd = false;
        static int array[length];
        if(!initd) {
            for(int i=0; i<length; ++i) {
                array[i] = i+1;
            }
            initd = true;
        }
        return array;
    };
};
模板
类myClass{
静态int*myArray(){
静态bool initd=false;
静态整数数组[长度];
if(!initd){

对于(int i=0;i我认为这只适用于C++0x。在C++03中,无论您做什么,最终都会得到一个动态初始化的数组,因此可能存在初始化顺序问题。下面的C++0x代码不会有这样的问题

template<int...>
struct myArray;

template<int N, int ...Ns>
struct myArray<N, Ns...> : myArray<N-1, N, Ns...> { };

template<int ...Ns>
struct myArray<0, Ns...> {
    static int array[sizeof...(Ns)];
};

template<int ...Ns>
int myArray<0, Ns...>::array[sizeof...(Ns)] = { Ns... } ;

template<int length>
class myClass : myArray<length> {
    using myArray<length>::array;
};
模板
结构myArray;
模板
结构myArray:myArray{};
模板
结构myArray{
静态int数组[sizeof…(Ns)];
};
模板
数组[sizeof…(Ns)]={Ns…};
模板
类myClass:myArray{
使用myArray::array;
};

“静态构造函数惯用法”给出0个结果;)这不是一个很好的习惯用法。很抱歉,在gcc-4.3下,这对我不起作用,静态构造函数从未被调用过……除了我们需要
myClass::StaticConstructor myClass::static\u constructor
。我们能安全地假设数组将在static\u构造函数之前初始化吗?我不确定静态数据成员是否定义了初始化顺序(与非静态成员相反,非静态成员。看起来它们应该按照类定义中声明的顺序初始化,但是…@Study472:在同一个翻译单元中,静态是按照它们出现的顺序实例化的。只有在翻译单元之间才会使它们未定义。是的,这不能这样做。您需要确保
static\u conststructor
始终被引用。否则,当用户仅引用
数组时,它将不会被填充。您的代码中还有一些关于模板使用的错误。如果您不确定,请测试您的答案。我不久前问了一个类似的问题:。但是使用
std::tr1::array
而不是此C样式数组…嘘t、 assign对于初始化任何类型的容器都非常有用:如果不实例化myClass会发生什么?如果没有我刚才编辑的修改,它将无法工作。
template<int length>
class myClass {
    static int* myArray() {
        static bool initd = false;
        static int array[length];
        if(!initd) {
            for(int i=0; i<length; ++i) {
                array[i] = i+1;
            }
            initd = true;
        }
        return array;
    };
};
myClass<4>::myArray()[2] = 42;
template<int...>
struct myArray;

template<int N, int ...Ns>
struct myArray<N, Ns...> : myArray<N-1, N, Ns...> { };

template<int ...Ns>
struct myArray<0, Ns...> {
    static int array[sizeof...(Ns)];
};

template<int ...Ns>
int myArray<0, Ns...>::array[sizeof...(Ns)] = { Ns... } ;

template<int length>
class myClass : myArray<length> {
    using myArray<length>::array;
};