【问题标题】:error: too many initializers for const [duplicate]错误:const 的初始化程序太多 [重复]
【发布时间】:2015-01-24 08:53:25
【问题描述】:

为什么会出现以下错误

$ g++ -std=c++11 aaa.cpp 

aaa.cpp:15:2: error: too many initializers for ‘const aaaa::Fruit_List [0]’

};

^

编译以下代码时:

class aaaa
{  // without wrapping in class the code compiles fine
    const int a=7; // compiles fine

    struct Fruit_List{
        int index;
        int length;
    } const fruit_list[]={ // error: if I put 5 in braket the code compiles fine
        {0,3},
        {1,2},
        {2,5},
        {3,1},
        {4,7}
    };
};

int main()
{
    return 0;
}

如果我编写代码而不包含在类中,它会编译得很好。给出数组的长度将抑制编译器错误。但坚持将代码放在类中并避免给出数组大小,因为我以后可能会添加任何成员,并且我想将数组长度确定留给编译器。

强烈,请避免链接到任何不适当的问题。

更新

感谢 juanchopanza 的评论。现在我知道即使是这个更简单的代码也无法编译:

class aaaa
{
    const int a[]={7,4,5};
};

int main()
{
    return 0;
}

【问题讨论】:

  • C++ 不允许T[] 类型的数据成员。您需要T[N],其中N 是一个常量表达式。您是在问为什么不允许这样做,还是只是在引用标准后确认不允许这样做?
  • @fredrik 对歧义感到抱歉。我修好了。
  • 即使你删除const,它仍然会报错。
  • 不,我说“C++ 不允许 T[] 类型的 数据成员。我猜 a 不是数据成员。在一个类中,你可以有T = {....}T{.....} 其中T 是一个完整的类型。Q[] 不满足。
  • 这个问题你必须问 C++ 标准委员会... ;) 我的猜测是它很难以有意义的方式确定整个结构的大小。如果你这样做怎么办:class a { const int b[]; }; ... const int a::b = { 1,2,3,4,5 }; 如果有固定大小,我认为这是允许的......如果a::b = .. 在另一个文件中怎么办?

标签: c++ c++11


【解决方案1】:

您可能理解,通过将其包装到一个类中,您假定的常量不再是引用具有在初始化常量时给出的固定值的对象的名称 .相反,您现在声明的是常量数据成员,它们类似于非常量数据成员,并且单独存在于该类的每个实例中。你提供的值无非是一个默认值,用于在构造函数中初始化常量成员。

考虑这个例子:

#include <ostream>
#include <iostream>

struct Demo {
  const int args[3];
  Demo() : args{1,2,3} {}
  Demo(int x) : args{x,x,x} {}
  Demo(int y, int z) : args{y, z} {}
};

int main(void)
{
  Demo d1;
  Demo d2(1,2);
  std::cout << d2.args[0] << ' ' << d2.args[1] << ' '
            << d2.args[2] << '\n';  // outputs "1 2 0"
  return 0;
}

并非所有构造函数都使用相同数量的值初始化Demo::args。这是有效的,剩余的元素是零填充的。您在类中为非静态数据成员提供的初始化只是语法糖,用于在每个构造函数中使用该值,其中在 init 列表中没有为该成员指定显式值,因此上面的示例也可以这样编写:

#include <ostream>
#include <iostream>

struct Demo {
  const int args[3] = {1,2,3};
  Demo() {}
  Demo(int x) : args{x,x,x} {}
  Demo(int y, int z) : args{y, z} {}
};

int main(void)
{
  Demo d1;
  Demo d2(1,2);
  std::cout << d2.args[0] << ' ' << d2.args[1] << ' '
            << d2.args[2] << '\n';  // outputs "1 2 0"
  return 0;
}

Demo::args 成员的初始化器不是 初始化器,而只是 一个 初始化器,而构造函数可以指定不同的初始化器。这很可能是不允许大小扣除的原因,就像您不能在非静态数据成员上使用 auto

如果您只是想在程序运行时始终将单个命名实体的名称与一个常量值放在一个类提供的命名空间中,但又不想在某些情况下获得指定不同值的能力构造函数,在类中使用static 常量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-25
    • 2012-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-22
    • 2016-02-23
    相关资源
    最近更新 更多