C ++ 11配列の初期化はコピーコンストラクターを呼び出さない

ブライアン・ロドリゲス

サイズに合わせてテンプレート化された配列を使用する小さなクラスを作成しています。ここにいくつかのコードがあります...

.hpp

template <size_t N>
class KeyCombinationListener
{
public:
    KeyCombinationListener(
        const std::array<sf::Keyboard::Key, N>& sequence,
        std::function<void (void)> fn
        );

private:
    std::array<sf::Keyboard::Key, N>  combo;
    std::function<void (void)>  callback;
};

.cc

template <size_t N>
KeyCombinationListener<N>::KeyCombinationListener(
    const array<sf::Keyboard::Key, N>& sequence, function<void (void)> fn
    ) : combo(sequence), progress{begin(combo)}, callback{fn}
{

}

コンストラクターのメンバー初期化では、combo{sequence}のみを受け入れるため、初期化子として使用できませんsf::Keyboard::Keyこれはinitializer_listを要求している場合は理にかなっていますが、これは私には奇妙に思えます。他の標準コンテナでは、{}表記を使用してコピーコンストラクタを呼び出すことができます。これは癖std::arrayですか?それとも私のclangのバグですか?

念のため、これが私のclangバージョンです。

Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)
Target: x86_64-pc-linux-gnu
Thread model: posix
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9.2
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9.2
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9
Candidate multilib: .;@m64
Selected multilib: .;@m64
深い

C ++で欠陥が発生しました:単一の要素からのリスト初期化。C ++ 11およびC ++ 14国際規格で指定されている動作は驚くべきものです。以下ではC ++ 14を参照します。

のテンプレートのインスタンス化はstd::array、集計[array.overview] / 2です。したがって、braced -init-liststd::arrayからオブジェクトを初期化する場合aggregate-initializationは、初期化子の数[dcl.init.list] /3.1とは無関係に実行されます。他のコンテナクラスは、特定の構造(たとえば、イテレータのペアから)の要件のために集約できません。

Aggregate-initializationは、初期化子からのデータメンバーを(潜在的に再帰的に)初期化します。あなたの場合、std::array<sf::Keyboard::Key, N>初期化子sequence(同じタイプ)からの最初のデータメンバーを初期化しようとしますstd::array私が知っているすべての実装では、の最初のデータメンバーstd::arrayはCスタイルの配列です。List-initializationは、元の初期化子からその配列の最初の要素を初期化しようとしますsequence

例:

struct aggregate
{
    int m[2];
};

aggregate x = {0, 1};
assert(x.m[0] == 0 && x.m[1] == 1);

aggregate y{x}; // error: cannot convert `aggregate` to `int`

最後の行の初期化は初期化しようとしますy.m[0]からx


CWG問題1467は、これと関連する問題、初期化子がない場合のリスト初期化について説明しています。提案された解決策は、OPの問題をカバーするリスト初期化の(さらに別の)特別なケースを導入します。最近のgithubドラフト[dcl.init.list] /3.1を引用

もしTクラス型と初期化リストは、型の単一要素有するCV UUであるTか、から派生したクラスT、オブジェクトが(コピーリストの初期化のためのコピー初期化によって、またはのための直接初期化することによって、その要素から初期化されます直接リスト初期化)。

最近のドラフトでの集計初期化の「優先度」(3.3)は低くなっています。つまり、上記の条件が満たされない場合にのみ実行されます。


g ++(5.0)およびclang ++(3.7.0)の最近のバージョンは、C ++ 11モードでも提案された解決策を実装しています。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

C ++仮想基本クラス:親のコピーコンストラクターが呼び出されない

分類Dev

C ++は、初期化リストの外部で親コンストラクターを明示的に呼び出します

分類Dev

コピーコンストラクターを削除してクラスの配列を初期化する方法(C ++ 11)

分類Dev

C#ベースコンストラクターが呼び出されないのはなぜですか?

分類Dev

基本クラスコンストラクターを呼び出さないC#での継承の問題

分類Dev

C ++なぜコピーコンストラクタが呼び出されたのですか?

分類Dev

C ++:moveコンストラクターが呼び出されないのはなぜですか?

分類Dev

C ++は、コピーコンストラクターではなくデフォルトコンストラクターを呼び出します

分類Dev

複数回呼び出されたC ++コピーコンストラクタ

分類Dev

C ++:コンストラクターを検討するが呼び出さないことの特殊性

分類Dev

C ++の基本的なCTORの説明-代入/コピーコンストラクターが呼び出されない理由

分類Dev

コピーコンストラクターのc ++呼び出し関数

分類Dev

コピーおよびベースコンストラクタはC ++を初期化しません

分類Dev

C ++でコピーコンストラクターが呼び出されるのはいつですか?オブジェクトを別のオブジェクトに割り当てるときに呼び出されませんか?

分類Dev

警告変数を初期化するためのコンストラクターからのC26495関数の呼び出し、なぜですか?

分類Dev

C ++プログラムのコピーコンストラクタが2回呼び出されるのはなぜですか?

分類Dev

C ++ベクトルemplace_backはコピーコンストラクターを呼び出します

分類Dev

コンストラクター内のすべてのメンバーを初期化しないクラスをC ++ 11で初期化する方法

分類Dev

initializer_list <>の代わりにC ++コピーコンストラクターが呼び出されます

分類Dev

C ++で作成済みのオブジェクトに実際にコピーしているのに、コピーコンストラクターが呼び出されるのはなぜですか?

分類Dev

継承:コンストラクター、C ++ 11の基本クラスの配列メンバーのようにCを初期化します

分類Dev

コピーコンストラクターが存在する場合にのみ呼び出す方法は?c ++

分類Dev

c ++ std変換はコピーコンストラクターを複数回呼び出します

分類Dev

呼び出されないC ++コンストラクタ

分類Dev

C ++の暗黙的なコピーコンストラクターをインターセプトするか、その機能を呼び出します

分類Dev

C ++ラムダ2コピーコンストラクター呼び出し

分類Dev

C ++のコンストラクターでc配列を初期化する際のエラー

分類Dev

c ++:コンストラクターがここで呼び出されるのはなぜですか

分類Dev

C ++-コピーコンストラクタまたは代入演算子を使用しない配列操作

Related 関連記事

  1. 1

    C ++仮想基本クラス:親のコピーコンストラクターが呼び出されない

  2. 2

    C ++は、初期化リストの外部で親コンストラクターを明示的に呼び出します

  3. 3

    コピーコンストラクターを削除してクラスの配列を初期化する方法(C ++ 11)

  4. 4

    C#ベースコンストラクターが呼び出されないのはなぜですか?

  5. 5

    基本クラスコンストラクターを呼び出さないC#での継承の問題

  6. 6

    C ++なぜコピーコンストラクタが呼び出されたのですか?

  7. 7

    C ++:moveコンストラクターが呼び出されないのはなぜですか?

  8. 8

    C ++は、コピーコンストラクターではなくデフォルトコンストラクターを呼び出します

  9. 9

    複数回呼び出されたC ++コピーコンストラクタ

  10. 10

    C ++:コンストラクターを検討するが呼び出さないことの特殊性

  11. 11

    C ++の基本的なCTORの説明-代入/コピーコンストラクターが呼び出されない理由

  12. 12

    コピーコンストラクターのc ++呼び出し関数

  13. 13

    コピーおよびベースコンストラクタはC ++を初期化しません

  14. 14

    C ++でコピーコンストラクターが呼び出されるのはいつですか?オブジェクトを別のオブジェクトに割り当てるときに呼び出されませんか?

  15. 15

    警告変数を初期化するためのコンストラクターからのC26495関数の呼び出し、なぜですか?

  16. 16

    C ++プログラムのコピーコンストラクタが2回呼び出されるのはなぜですか?

  17. 17

    C ++ベクトルemplace_backはコピーコンストラクターを呼び出します

  18. 18

    コンストラクター内のすべてのメンバーを初期化しないクラスをC ++ 11で初期化する方法

  19. 19

    initializer_list <>の代わりにC ++コピーコンストラクターが呼び出されます

  20. 20

    C ++で作成済みのオブジェクトに実際にコピーしているのに、コピーコンストラクターが呼び出されるのはなぜですか?

  21. 21

    継承:コンストラクター、C ++ 11の基本クラスの配列メンバーのようにCを初期化します

  22. 22

    コピーコンストラクターが存在する場合にのみ呼び出す方法は?c ++

  23. 23

    c ++ std変換はコピーコンストラクターを複数回呼び出します

  24. 24

    呼び出されないC ++コンストラクタ

  25. 25

    C ++の暗黙的なコピーコンストラクターをインターセプトするか、その機能を呼び出します

  26. 26

    C ++ラムダ2コピーコンストラクター呼び出し

  27. 27

    C ++のコンストラクターでc配列を初期化する際のエラー

  28. 28

    c ++:コンストラクターがここで呼び出されるのはなぜですか

  29. 29

    C ++-コピーコンストラクタまたは代入演算子を使用しない配列操作

ホットタグ

アーカイブ