C++0x 不使用构造函数进行成员初始化

发布于 2024-12-01 14:41:38 字数 1620 浏览 3 评论 0原文

N3257 中,我找到了一个使用的示例在没有构造函数的情况下初始化成员,这很好。我想这是可能的,因为它是一个 POD。

template<typename T>
struct adaptor {
    NonStdContainer<T>* ptr;                // <- data member
    T* begin() { return ptr->getFirst(); }
    T* end() { return ptr->getLast() + 1; }
};
void f(NonStdContainer<int>& c) {
    for (auto i : adaptor<int>{&c})         // <- init
        { /* ... */ }
}

当我玩这个例子时,我用 & 替换了 * ,因为我不喜欢原始指针:

template<typename T>
struct adaptor {
    NonStdContainer<T>& ptr;                // <- data member, now REF
    T* begin() { return ptr->getFirst(); }
    T* end() { return ptr->getLast() + 1; }
};
void f(NonStdContainer<int>& c) {
    for (auto i : adaptor<int>{c})         // <- init
        { /* ... */ }
}

这很好,并且使用 GCC-4.7 进行编译时没有警告.0。

然后我对 POD 的初始化以及 C++0x 可能发生的变化感到好奇。 在那里我找到了 Bjarnes FAQ。他在那里说 POD 可能包含指针,但没有引用

Ops,现在我想知道:

  • 这里是否有非 POD 对象,编译器无论如何都可以在没有构造函数的情况下初始化它,而我只是想念这里使用了哪些机制?
  • 或者让我以这种方式初始化引用,GCC-4.7.0 的行为是否非标准
  • 或者自 Bjarnes FAQ 以来 std 是否发生了变化,也允许在 POD 中引用?

更新: 我在当前 std 中发现了聚合8.5.1 聚合 [dcl.init.aggr]),但是那里没有提到引用,所以我不确定它们与此有何关系

In N3257 I found an example using initializing members without a constructor, which is fine. I guess that is possible, because it is a POD.

template<typename T>
struct adaptor {
    NonStdContainer<T>* ptr;                // <- data member
    T* begin() { return ptr->getFirst(); }
    T* end() { return ptr->getLast() + 1; }
};
void f(NonStdContainer<int>& c) {
    for (auto i : adaptor<int>{&c})         // <- init
        { /* ... */ }
}

When I played around with this example I replaced the * with a &, because I don't like raw pointers:

template<typename T>
struct adaptor {
    NonStdContainer<T>& ptr;                // <- data member, now REF
    T* begin() { return ptr->getFirst(); }
    T* end() { return ptr->getLast() + 1; }
};
void f(NonStdContainer<int>& c) {
    for (auto i : adaptor<int>{c})         // <- init
        { /* ... */ }
}

This was fine and compiled without warning with GCC-4.7.0.

Then I got curious about the initialization of PODs and what might have changed with C++0x.
There I found Bjarnes FAQ. He says there that PODs may contain pointers, but no references.

Ops, now I wonder:

  • Do I have non-POD-object here, which the compiler can initialize without a constructor anyway and I just miss which mechanisms are used here?
  • or Is the GCC-4.7.0 behaving non-std by letting me initializing the ref this way?
  • or has there been a change in the std since Bjarnes FAQ that also allows references in PODs?

Update: I found aggregates in the current std (8.5.1 Aggregates [dcl.init.aggr]), but references are not mentioned there, so I am not sure how they relate to this

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

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

发布评论

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

评论(1

叫嚣ゝ 2024-12-08 14:41:38

引用标准[dcl.init.aggr]:

聚合是一个数组或一个类(第 9 条),没有用户提供的
构造函数 (12.1),非静态没有大括号或等号初始化器
数据成员 (9.2),没有私有或受保护的非静态数据成员
(第 11 条),没有基类(第 10 条),并且没有虚函数
(10.3)。

当聚合由初始化列表初始化时,如指定的
在 8.5.4 中,初始化列表的元素被视为
聚合成员的初始值设定项,下标递增
或会员订单。每个成员都是从相应的初始化子句中复制初始化的...

这意味着您在这里有一个聚合,可以按照您的方式初始化聚合。 POD 与此无关,它们实际上是用于与例如进行通信。 C.

使用变量复制初始化引用当然是合法的,因为这意味着

T& ref = c;

我这里是否有非 POD 对象,编译器无论如何都可以在没有构造函数的情况下初始化它,而我只是想念这里使用了哪些机制?

是的,该对象是非 POD。

让我以这种方式初始化引用,GCC-4.7.0 是否表现出非标准行为?

不。

Quoting the standard [dcl.init.aggr]:

An aggregate is an array or a class (Clause 9) with no user-provided
constructors (12.1), no brace-or-equal- initializers for non-static
data members (9.2), no private or protected non-static data members
(Clause 11), no base classes (Clause 10), and no virtual functions
(10.3).

When an aggregate is initialized by an initializer list, as specified
in 8.5.4, the elements of the initializer list are taken as
initializers for the members of the aggregate, in increasing subscript
or member order. Each member is copy-initialized from the corresponding initializer-clause...

That means you have an aggregate here, aggregates can be initialized how you do it. PODs have nothing to do with it, they are really meant for communication with eg. C.

Copy-initialization of a reference with a variable is certainly legal, because that just means

T& ref = c;

Do I have non-POD-object here, which the compiler can initialize without a constructor anyway and I just miss which mechanisms are used here?

Yes, the object is non-POD.

Is the GCC-4.7.0 behaving non-std by letting me initializing the ref this way?

No.

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