为什么不能通过直接初始化语法来初始化类数据成员?

发布于 2025-01-09 04:35:09 字数 529 浏览 4 评论 0原文

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

#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 [错误] 数字常量之前的预期标识符

11 9 [错误] 数字常量前应有“,”或“...”

为什么? C++ 标准对类数据成员的初始化有何规定?

I am curious to know why class data members can't be initialized using the () syntax? Consider the following example:

#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;
}

The program fails in compilation & gives the following errors"

11 9 [Error] expected identifier before numeric constant

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

Why? What does the C++ standard say about initialization of class data members?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你好,陌生人 2025-01-16 04:35:09

导致该功能推出的早期提案解释说这是为了避免解析问题

以下只是其中提供的示例之一:

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

<前><代码>结构S {
整数 i(x); // 带初始值设定项的数据成员
// ...
静态 int x;
};

结构体 T {
整数 i(x); // 成员函数声明
// ...
typedef int x;
};

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

<前><代码>结构S {
整数 i(j); // 格式错误...解析为成员函数,
// 输入 j 已查找但未找到
// ...
静态整型 j;
};

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

<前><代码>结构S {
整数 i(x); // 明确的数据成员
int j(类型名 y); // 毫无疑问是一个成员函数
};

这两种解决方案都引入了可能被许多用户误解的微妙之处(正如 comp.lang.c++ 上关于为什么在块范围内使用“int i();”的许多问题所证明的那样未声明默认初始化的 int)。

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

Early proposals leading to the feature's introduction explain that this is to avoid parsing problems.

Here's just one of the examples presented therein:

Unfortunately, this makes initializers of the “( expression-list )” form ambiguous at the time that the declaration is being parsed:

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

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

One possible solution is to rely on the existing rule that, if a declaration could be an object or a function, then it’s a function:

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

A similar solution would be to apply another existing rule, currently used only in templates, that if T could be a type or something else, then it’s something else; and we can use “typename” if we really mean a type:

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

Both of those solutions introduce subtleties that are likely to be misunderstood by many users (as evidenced by the many questions on comp.lang.c++ about why “int i();” at block scope doesn’t declare a default-initialized int).

The solution proposed in this paper is to allow only initializers of the “= initializer-clause” and “{ initializer-list }” forms. That solves the ambiguity problem in most cases. [..]

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文