C++ 元编程:使用常量数组

C++ 元编程:使用常量数组,c++,constants,metaprogramming,template-meta-programming,C++,Constants,Metaprogramming,Template Meta Programming,我是元编程新手,在使用选项卡时遇到了与常量相关的问题 假设我们有几种“类型”。每种类型都有不同的版本,我们将能够处理每种类型的所有vesrion。为此,我们使用一个包含类型标准信息的结构,以及一个包含每个版本信息的数组 问题是,每种类型的版本数量并不相同。另外,版本号不是很高,所以我不喜欢使用上述表的动态分配。但是如果我进行静态分配,我需要为结构的每个实例提供一个大小相同的表。这意味着,我必须获得最高的版本值,并将其用作数组的大小 我来了:我想创建一个小的元编程模板,它在编译时提供最高的版本值,

我是元编程新手,在使用选项卡时遇到了与常量相关的问题

假设我们有几种“类型”。每种类型都有不同的版本,我们将能够处理每种类型的所有vesrion。为此,我们使用一个包含类型标准信息的结构,以及一个包含每个版本信息的数组

问题是,每种类型的版本数量并不相同。另外,版本号不是很高,所以我不喜欢使用上述表的动态分配。但是如果我进行静态分配,我需要为结构的每个实例提供一个大小相同的表。这意味着,我必须获得最高的版本值,并将其用作数组的大小

我来了:我想创建一个小的元编程模板,它在编译时提供最高的版本值,这样我就可以有一个固定大小的数组,其中肯定包含每种类型的necerrasy信息。但是我得到了一个编译错误

下面是一个简化的示例代码,用于重现问题(错误如下)

@台词

VALUE = (typeVersions[i] > PREVIOUS ? typeVersions[i] : PREVIOUS)

似乎编译器告诉我表的内容不是常量。我假设这是因为表被解释为一个指针,在这种情况下它不是常数(因此,如果指针改变,内容就不一样)。有没有办法纠正这一点,以便我可以使用脚本?这将使用户无需手动设置该表的大小


提前感谢:)

我甚至不确定使用静态数组是否可以实现此功能。
一个可能的替代方案是特征类:

template<TYPES>
struct typeVersions;

// specializations for each type

template<>
struct typeVersions<T_ALPHA> { static const int version = VERSION_ALPHA; };
template<>
struct typeVersions<T_BETA> { static const int version = VERSION_BETA; };
// etc...
模板
结构类型版本;
//每种类型的专门化
模板
结构类型版本{static const int version=version_ALPHA;};
模板
结构类型版本{static const int version=version_BETA;};
//等等。。。
您可以这样使用它:

enum {
    VALUE = typeVersions<i>::version
};
enum{
VALUE=typeVersions::version
};

我不确定是否可以用C风格的数组来实现这一点,但如果您有C++11编译器支持,请检查我的解决方案:

#include <array>
#include <iostream>

template <int Size, int Indice>
struct HighestValue
{
    static int get(std::array<int, Size> checkedArray) {
        return std::max(HighestValue<Size, Indice - 1>::get(checkedArray), checkedArray[Indice]);
    }
};

template <int Size>
struct HighestValue<Size, 0>
{
    static int get(std::array<int, Size> checkedArray) {
        return checkedArray[0];   
    }
};

template<size_t Size>
int checkMax(std::array<int, Size> checkedArray)
{
    return HighestValue<Size, Size - 1>::get(checkedArray);   
}

int main()
{
    std::array<int, 7> test {1, 5, 2, 3, 123, 5, 2};
    std::cout << checkMax(test);
}
#包括
#包括
模板
结构最高值
{
静态int get(std::array checkedArray){
返回std::max(最高值::get(checkedArray),checkedArray[Indice]);
}
};
模板
结构最高值
{
静态int get(std::array checkedArray){
返回校验数组[0];
}
};
模板
int checkMax(标准::数组checkedArray)
{
返回最高值::get(checkedArray);
}
int main()
{
数组测试{1,5,2,3,123,5,2};

正如jrok所说,使用静态数组很可能不可能做到这一点,但也不可能 如果您有一个适当的属性,那么为每个类型版本创建特征专门化是必要的 C++11编译器

我看到您正在使用VC++并且您可能已经投入使用,这很遗憾意味着您现在可能拥有或着手使用的唯一符合要求的C++11编译器是VC++2013预览版。如果您可以使用它,那么下面对您的程序所做的修改说明的简单可变模板解决方案将适用于您:

#include <stdio.h>

// change values here
#define VERSION_ALPHA 3
#define VERSION_BETA 5
#define VERSION_GAMMA 2

// different available types
enum TYPES
{
    T_ALPHA = 0,
    T_BETA,
    T_GAMMA,
    T_COUNT, // number of types
};

template<int ...Versions>
struct versions_list
{
    static_assert(sizeof ...(Versions),
        "Cannot have 0 versions");
};

template<int Only>
struct versions_list<Only>
{
    static const int max = Only;
};

template<int First, int Last>
struct versions_list<First,Last>
{
    static const int max = First > Last ? First : Last;
};

template<int First, int Second, int ...Rest>
struct versions_list<First,Second,Rest...>
{
    static const int tail_max = versions_list<Second,Rest...>::max;
    static const int max = First > tail_max ? First : tail_max;
};

// Update your version list here:
typedef versions_list<VERSION_ALPHA, VERSION_BETA, VERSION_GAMMA> typeVersions;

#define HIGHEST_VERSION typeVersions::max


// holds info about a single type
struct TypeInfo
{
    char * s_pName; // name of the type as string
    unsigned int s_Flags[HIGHEST_VERSION]; // flags for each available version of this type
};


int main()
{
    // instanciate
    TypeInfo infos[T_COUNT];

    // do stuff, set name, load flags....
    /*...*/

    // for test purpose, print max version value (should print 5 in this situation)
    printf("%d\n", HIGHEST_VERSION);
}
#包括
//在此处更改值
#定义版本3
#定义版本_BETA 5
#定义版本2
//不同的可用类型
枚举类型
{
T_α=0,
T_BETA,
T_GAMMA,
T\u计数,//类型数
};
模板
结构版本列表
{
静态断言(sizeof…(版本),
“不能有0个版本”);
};
模板
结构版本列表
{
静态常数int max=仅限;
};
模板
结构版本列表
{
静态常数int max=First>Last?First:Last;
};
模板
结构版本列表
{
静态常量int tail_max=版本列表::max;
静态常数int max=First>tail_max?First:tail_max;
};
//在此处更新您的版本列表:
typedef版本\列出typeVersions;
#定义最高版本typeVersions::max
//保存有关单个类型的信息
结构类型信息
{
char*s_pName;//类型的名称为字符串
unsigned int s_Flags[最高版本];//此类型的每个可用版本的标志
};
int main()
{
//实例化
类型信息[T_计数];
//完成任务、设置名称、加载标志。。。。
/*...*/
//出于测试目的,打印最大版本值(在这种情况下应打印5)
printf(“%d\n”,最高版本);
}
在这里,
HIGHEST\u VERSION
宏实际上毫无意义:您可以删除它的定义,并用
typeVersions::max
替换所有出现的内容

顺便说一下,如果你真的想在C++程序中使用C的<代码> STDIO < /Cord>API,而不是C++
iostream
API,严格来说,您应该使用
#include
,而不是
#include

如果您将值更改为static const int而不是enum,会发生什么情况?我认为您需要在某个地方使用constepr功能,但我的编译器不支持它。抱歉,同样的问题。IDE在部件typeVersions[I]下面划线,这可能意味着错误来自这里。我来看看“constexpr”(不知道它是什么)我不认为编译器认为数组元素是常量表达式,即使数组是常量并且在编译时已知。constexpr似乎不受visual studio 2012编译器的支持…明白了,它被编译了。我对必须这样做感到震惊(明白了,但不知道它被称为“trait”)但这似乎是唯一的解决办法。谢谢。
enum {
    VALUE = typeVersions<i>::version
};
#include <array>
#include <iostream>

template <int Size, int Indice>
struct HighestValue
{
    static int get(std::array<int, Size> checkedArray) {
        return std::max(HighestValue<Size, Indice - 1>::get(checkedArray), checkedArray[Indice]);
    }
};

template <int Size>
struct HighestValue<Size, 0>
{
    static int get(std::array<int, Size> checkedArray) {
        return checkedArray[0];   
    }
};

template<size_t Size>
int checkMax(std::array<int, Size> checkedArray)
{
    return HighestValue<Size, Size - 1>::get(checkedArray);   
}

int main()
{
    std::array<int, 7> test {1, 5, 2, 3, 123, 5, 2};
    std::cout << checkMax(test);
}
#include <stdio.h>

// change values here
#define VERSION_ALPHA 3
#define VERSION_BETA 5
#define VERSION_GAMMA 2

// different available types
enum TYPES
{
    T_ALPHA = 0,
    T_BETA,
    T_GAMMA,
    T_COUNT, // number of types
};

template<int ...Versions>
struct versions_list
{
    static_assert(sizeof ...(Versions),
        "Cannot have 0 versions");
};

template<int Only>
struct versions_list<Only>
{
    static const int max = Only;
};

template<int First, int Last>
struct versions_list<First,Last>
{
    static const int max = First > Last ? First : Last;
};

template<int First, int Second, int ...Rest>
struct versions_list<First,Second,Rest...>
{
    static const int tail_max = versions_list<Second,Rest...>::max;
    static const int max = First > tail_max ? First : tail_max;
};

// Update your version list here:
typedef versions_list<VERSION_ALPHA, VERSION_BETA, VERSION_GAMMA> typeVersions;

#define HIGHEST_VERSION typeVersions::max


// holds info about a single type
struct TypeInfo
{
    char * s_pName; // name of the type as string
    unsigned int s_Flags[HIGHEST_VERSION]; // flags for each available version of this type
};


int main()
{
    // instanciate
    TypeInfo infos[T_COUNT];

    // do stuff, set name, load flags....
    /*...*/

    // for test purpose, print max version value (should print 5 in this situation)
    printf("%d\n", HIGHEST_VERSION);
}