4

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 は、この方法で参照を初期化することによって非標準の動作をしていますか?
  • または、POD での参照も許可する Bjarnes FAQ 以来、std に変更がありましたか?

更新:現在の std ( 8.5.1 Aggregates [dcl.init.aggr] ) で集計が見つかりましたが、そこには参照が記載されていないため、それらがこれにどのように関連しているかはわかりません

4

1 に答える 1

4

標準 [dcl.init.aggr] の引用:

集約は、ユーザー提供のコンストラクター (12.1)、非静的データ メンバー用のブレースまたはイコール イニシャライザー (9.2)、プライベートまたは保護された非静的データ メンバー (条項 11)、基本クラスなし (条項 10)、および仮想関数なし (10.3)。

8.5.4 で指定されているように、集合体が初期化子リストによって初期化される場合、初期化子リストの要素は、添え字またはメンバーの昇順で、集合体のメンバーの初期化子として取得されます。各メンバーは、対応する初期化句からコピー初期化されます...

つまり、ここに集計があることを意味します。集計は、その方法で初期化できます。PODはそれとは何の関係もありません。実際には、たとえば. C.

変数を使用した参照のコピー初期化は確かに合法です。

T& ref = c;

とにかく、コンパイラーがコンストラクターなしで初期化できる非PODオブジェクトがここにありますか?ここで使用されているメカニズムを見逃していますか?

はい、オブジェクトは非 POD です。

この方法で参照を初期化することで、GCC-4.7.0 は非標準の動作をしていますか?

いいえ。

于 2011-09-10T13:27:57.050 に答える