Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 正在初始化枚举索引数组?_C++_Arrays_Gcc_Enums_G++ - Fatal编程技术网

C++ 正在初始化枚举索引数组?

C++ 正在初始化枚举索引数组?,c++,arrays,gcc,enums,g++,C++,Arrays,Gcc,Enums,G++,gcc在C中有一个非常好的扩展,允许您使用enum作为键在数组中保存数据: enum keys { key_alpha = 0, key_beta = 1, key_gamma = 2 }; ValType values = { [ key_alpha ] = { 0x03b1,"alpha" }, [ key_gamma ] = { 0x03b3,"gamma" }, [ key_beta ] = { 0x

gcc在C中有一个非常好的扩展,允许您使用enum作为键在数组中保存数据:

 enum keys
 {
      key_alpha = 0,
      key_beta = 1,
      key_gamma = 2
 };

 ValType values = 
 {
      [ key_alpha ] = { 0x03b1,"alpha" },
      [ key_gamma ] = { 0x03b3,"gamma" },
      [ key_beta ]  = { 0x03b2,"beta" }
 };
这很好,因为如果列表必须更改,添加或删除一行不会破坏赋值,很明显哪个键对应哪个值,并且生成的简单代码与普通标准数组初始化没有什么不同

不幸的是,这个扩展在g++中不可用


<>在C++中,做同样的事情的首选轻量级方法是什么?最好是一些不基于或类似使用字符串键、隐藏索引、重模板或其他CPU和内存重的东西的东西?

我怀疑这种扩展的存在正是因为没有简单、可移植的方法来实现这种行为。您可以使用以下方法进行模拟:

enum keys
{
  key_alpha = 0,
  key_beta = 1,
  key_gamma = 2
};

struct ValType {
  int v;
  const char *name;
};

template <int key>
struct param;

#define SETPARAM(key,value1,value2) \
template <> \
struct param< (key) > { \
  static constexpr ValType t {(value1),(value2)}; \
}

SETPARAM(key_alpha, 0x03b1,"alpha");
SETPARAM(key_gamma, 0x03b3,"gamma");
SETPARAM(key_beta, 0x03b2,"beta");
诀窍是实例化
get\u helper
,并使用一个可用于断言索引有效性的标志递归调用。如果需要,可以增加
MAXPARAM
,但这会降低编译速度

示例用法仍然非常简单:

#include "enumidx.hh"
#include <iostream>

SETPARAM(key_alpha, 0x03b1,"alpha");
SETPARAM(key_gamma, 0x03b3,"gamma");
SETPARAM(key_beta, 0x03b2,"beta");

int main() {
  int key = key_beta;
  const ValType& v = GETPARAM(key);
  std::cout << v.name << std::endl;
}
#包括“enumidx.hh”
#包括
SETPARAM(键_alpha,0x03b1,“alpha”);
SETPARAM(键_gamma,0x03b3,“gamma”);
SETPARAM(键_beta,0x03b2,“beta”);
int main(){
int key=key_β;
const ValType&v=GETPARAM(键);
std::cout
#包括
#定义键\
键定义(alpha,0x03b1,“alpha”)\
密钥定义(beta,0x03b2,“beta”)\
按键定义(伽马,0x03b3,“伽马”)
#定义密钥定义(标识符、id、名称)标识符
枚举键{keys_DEF};
#未定义键定义
#定义键定义(标识符、id、名称){id、名称}
struct ValType{int id;char const*name;};
ValType常量值[]={KEYS_DEF};
int main()
{
使用名称空间std;

对于(int i=alpha;i一个便宜、狡猾、欺诈的解决方案:在一个单独的.c文件中,在所有.cpp文件旁边定义“values”变量,在一个.h文件中定义enum和“extern values”。

c++11在解决方案中可以接受吗?它被称为
指定的初始值设定项
,在C99中可用,编译器可以将其作为扩展名提供。(顺便说一下,你的示例代码缺少分号)@纳瓦兹:GCC默认是这样的,GCC扩展页面将它具体地列为不存在于G++中的一个特征。我们可以将问题重新表述为:“C++中是否可以通过指定任意顺序的元素来初始化数组?”这不允许动态查找,所以我认为它不是一个有效的替代品。@BenVoigt-你可能就在那里,我没有想到。你的意思是例如
int I=someinput();但不幸的是,这意味着它对我没有好处。它通常嵌套在函数中,键作为参数传递。@SF-我可以解决这个问题,但它将它进一步扩展到“重模板”领域。我不认为你会得到一个基本上不只是
std::map
或“重模板”的答案@SF-answer更新了。我也可以修改它使它更通用,但是事情开始变得更复杂!Android init files parser中有一个很好的例子。c中的值和变量。
#include "enumidx.hh"
#include <iostream>

SETPARAM(key_alpha, 0x03b1,"alpha");
SETPARAM(key_gamma, 0x03b3,"gamma");
SETPARAM(key_beta, 0x03b2,"beta");

int main() {
  int key = key_beta;
  const ValType& v = GETPARAM(key);
  std::cout << v.name << std::endl;
}
#include <iostream>

#define KEYS_DEF \
    KEY_DEF( alpha, 0x03b1, "alpha" ),  \
    KEY_DEF( beta,  0x03b2, "beta" ),   \
    KEY_DEF( gamma, 0x03b3, "gamma" )

#define KEY_DEF( identifier, id, name )  identifier
enum keys { KEYS_DEF };

#undef KEY_DEF
#define KEY_DEF( identifier, id, name )  { id, name }
struct ValType { int id; char const* name; };
ValType const values[] = { KEYS_DEF };

int main()
{
    using namespace std;
    for( int i = alpha;  i <= gamma;  ++i )
    {
        cout << values[i].name << endl;
    }
}