【问题标题】:Why class data members can't be initialized by direct initialization syntax?为什么不能通过直接初始化语法来初始化类数据成员?
【发布时间】:2015-02-24 13:05:11
【问题描述】:

我很想知道为什么类的数据成员不能使用 () 语法初始化?考虑以下示例:

#include <iostream>
class test
{
    public:
        void fun()
        {
            int a(3);
            std::cout<<a<<'\n';
        }
    private:
        int s(3);    // Compiler error why???
};
int main()
{
    test t;
    t.fun();
    return 0;
}

程序编译失败并出现以下错误。

11  9 [Error] expected identifier before numeric constant

11  9 [Error] expected ',' or '...' before numeric constant

为什么?是什么原因? C++ 标准对类数据成员的初始化有何规定? 非常感谢您的帮助。谢谢

【问题讨论】:

  • “那为什么不能使用 () 语法初始化类的数据成员?” 因为语言标准是这样说的?
  • @πάνταῥεῖ:也许这里也应该有一个语言律师标签;我觉得问题更多:为什么在其他地方都允许这种做法时,标准会明确禁止这种做法?
  • 有几种不同的初始化语法,每一种只在某些地方有效,这就是为什么要为 C++11 开发统一的初始化语法。
  • @ArunA.S:不相关的评论。这可以按原样实现,只需将( 更改为{ 并将) 更改为}。无需重构所有内容。

标签: c++ initialization language-lawyer


【解决方案1】:

Early proposals leading to the feature's introduction 解释一下this is to avoid parsing problems

这里只是其中的一个例子:

不幸的是,这使得“( 表达式列表 )”形式的初始化器在解析声明时变得模棱两可:

struct S {
    int i(x); // data member with initializer
    // ...
    static int x;
};

struct T {
    int i(x); // member function declaration
    // ...
    typedef int x;
};

一种可能的解决方案是依赖于现有规则,即如果声明可以是对象或函数,那么它就是函数:

struct S {
    int i(j); // ill-formed...parsed as a member function,
              // type j looked up but not found
    // ...
    static int j;
};

类似的解决方案是应用另一个现有规则,目前仅在模板中使用,如果T 可以是类型或其他东西,那么它就是其他东西;如果我们真的是指类型,我们可以使用“typename”:

struct S {
    int i(x); // unabmiguously a data member
    int j(typename y); // unabmiguously a member function
};

这两种解决方案都引入了许多用户可能会误解的微妙之处(comp.lang.c++ 上关于为什么“int i();”在块范围内没有声明默认初始化的 @ 987654331@).

本文提出的解决方案是只允许“=initializer-clause”和“{initializer-list}”的初始化器形式。这解决了大多数情况下的歧义问题。 [..]

【讨论】:

  • 这个类的结果是什么?类 Foo { Foo() : x = 1 { } int x(2); };
  • @GoswinvonBrederlow:视情况而定。它遵循什么假设的语法规则?
  • @LightnessRacesinOrbit:j 类型查了没找到是什么意思?
  • @meet 表示编译器会尝试在你的程序中寻找一个名为j的类型,会失败。
  • @Lightness Races in Orbit:它遵循问题中的假设规则。我试图提出的一点是,当 x 被初始化两次时会令人困惑。但是当不同的构造函数使用不同的值时,需要在构造函数中进行初始化。因此,为了使其保持清醒,省略的是在类的主体中进行初始化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-22
相关资源
最近更新 更多