c – typedef of template包含char [] [] – 适用于VS2008但不适用于gcc

我有一些我正在使用的库代码.

它在Visual Studio(2008)下编译和工作,但不是GCC(v4.8.4.)

在标题中我们有:

extern const char menu_styles[MENU_COUNT][MAX_LEN];

typedef SysEnum <s_type_t, c_long, no_style, un_style, MAX_LEN, (char *)&menu_styles> MenuStyleEnum;

SysEnum的位置(在另一个文件中定义):

template<class ETYPE, class BTYPE, int MINV, int MAXV, int MLEN, char* pStr> class SysEnum

和gcc borks错误:

error: ‘menu_styles’ cannot appear in a constant-expression

我完全赞同. (此外,它是const char * cast to char *).

我希望VS2008只使用const char *而不是menu_styles来编译这个typedef,但我真的不确定.

我担心VisualSudio会添加某种类似构造函数的代码,因此无论何时使用此typedef,此char *确实指向menu_styles.

在使用GCC进行编译时,我可以用什么来交换它?

最佳答案 你的问题归结为编译

extern const char menu_styles[MENU_COUNT][MAX_LEN];

template<const char* pStr> class SysEnum{
  ...
};

typedef SysEnum <???> MenuStyleEnum;

我将模板参数更改为const char *,因为否则你必须抛弃constness并且这不是很好的事情.基本上问题是什么???应该.

定义char *模板参数的最常用方法是在某处使用char []变量,这将变为char *使每个人都满意:

extern const char menu_style0[MAX_LEN];
typedef SysEnum <menu_style0> MenuStyleEnum;//compiles...

但是,正如评论中已经指出的那样,该标准不允许我们执行以下任何操作:

typedef SysEnum <menu_styles[0]> MenuStyleEnum;
typedef SysEnum <*menu_styles> MenuStyleEnum;
typedef SysEnum <static_cast<const char *>(&menu_styles)> MenuStyleEnum;

我不确定技术限制是否是这种行为的原因,毕竟在编译时可以找出menu_styles [0]的地址(并且VS就是这样).我的猜测是它不会编译,因为标准是这样说的.

这不会让你有很多选择.如果SysEnum仅使用pStr指向的值(代码如cout<< pStr)并且地址本身并不重要(对于像pStr == otherCharPointer这样的代码就是这种情况),那么下面的解决方法可能是可能性:

#define _MENU_STYLE0_ "STYLE0" 
...

extern const char menu_style0[MAX_LEN]= _MENU_STYLE0_;
...

extern const char menu_styles[MENU_COUNT][MAX_LEN]={ _MENU_STYLE0_,  _MENU_STYLE1_, ...};
...

typedef SysEnum <menu_style0> MenuStyleEnum;//compiles!

缺点是,menu_styleX和menu_styles中存在相同的信息,这不是一个很好的解决方案.

如果menu_styles中的值只能是模板参数,则可以更容易声明:

template<size_t Index> class SysEnum{
    //use menu_styles[index] for pStr
};

typedef SysEnum <0> MenuStyleEnum;

但是,除了存储在menu_styles中之外,您将失去使用值的可能性,并且需要在SysEnum中进行一些重构.

点赞