サイズに合わせてテンプレート化された配列を使用する小さなクラスを作成しています。ここにいくつかのコードがあります...
.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
クラス型と初期化リストは、型の単一要素有するCVU
、U
であるT
か、から派生したクラスT
、オブジェクトが(コピーリストの初期化のためのコピー初期化によって、またはのための直接初期化することによって、その要素から初期化されます直接リスト初期化)。
最近のドラフトでの集計初期化の「優先度」(3.3)は低くなっています。つまり、上記の条件が満たされない場合にのみ実行されます。
g ++(5.0)およびclang ++(3.7.0)の最近のバージョンは、C ++ 11モードでも提案された解決策を実装しています。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加