C++ 为什么类数据成员可以';不能用直接初始化语法初始化吗?

C++ 为什么类数据成员可以';不能用直接初始化语法初始化吗?,c++,initialization,language-lawyer,C++,Initialization,Language Lawyer,我很想知道为什么类的数据成员不能用()语法初始化?考虑下面的例子: #include <iostream> class test { public: void fun() { int a(3); std::cout<<a<<'\n'; } private: int s(3); // Compiler error why??? }

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

#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;
}
为什么??原因是什么?C++标准如何描述类数据成员的初始化? 非常感谢你的帮助。谢谢你解释一下

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

不幸的是,这使得“
表达式列表
”表单的初始值设定项在解析声明时不明确:

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());< /代码>为什么不声明缺省初始化<代码> int <代码>的许多问题。 本文提出的解决方案是只允许使用“

=
初始值设定项子句”和“
{
初始值设定项列表
}
”表单的初始值设定项。这解决了大多数情况下的歧义问题。[……]


“这就是为什么不能使用()语法初始化类的数据成员?”因为语言标准这么说?@πάνταῥεῖ: 也许这里也应该有一个语言律师标签;我觉得问题更多的是:为什么在其他地方都允许这种做法的情况下,标准会明确禁止这种做法?事实上,有几种不同的初始化语法,每种都只在某些地方起作用,这就是为什么为C++11开发了统一的初始化语法。@ArunA.S:不相关的注释。这可以按原样实现,只需更改
{
。不需要重构所有东西。这个类的结果是什么?类Foo{Foo():x=1{}intx(2);}@GoswinvonBrederlow:视情况而定。它遵循什么假设的语法规则?@LightnessRacesinOrbit:j类型被查找但未找到是什么意思?@meet它意味着编译器将尝试在您的程序中找到一个名为
j
的类型,它将失败。@Lightness在轨道上比赛:它遵循问题中的假设规则。我试图提出的一点是,当x被初始化两次时,它会令人困惑。但是当不同的构造函数使用不同的值时,需要在构造函数中初始化。因此,为了使它正常,需要省略的是在类的主体中初始化。
struct S {
    int i(x); // unabmiguously a data member
    int j(typename y); // unabmiguously a member function
};