この質問に答えた後、私はこれを思いついた
シンプルな関数テンプレート (C++11) がありました。
template<class elem_t, class list_t>
bool in_list(const elem_t& elem, const list_t& list) {
for (const auto& i : list) {
if (elem == i) {
return true;
}
}
return false;
}
しかし、GCC はテンプレート パラメーターを std::initializer_list として推測することを好まないように見えるため、警告を発しました。だから、何も考えずに、私は専門化しました:
template<class elem_t>
bool in_list(const elem_t& elem, std::initializer_list<elem_t> list) {
for (const auto& i : list) {
if (elem == i) {
return true;
}
}
return false;
}
これはうまくいきました。もう警告はありません。しかし、改めて考えてみると、C++ は関数テンプレートの部分的なテンプレート特殊化をサポートしていないことを思い出しました。しかし、それはこれがそうであるように見えるものです。私の唯一の推測は、std::initializer_list がまだテンプレート パラメータに依存しているため、これが許可されているということです。したがって、本質的には別のテンプレートです。しかし、これが本来あるべき姿かどうかはわかりません (テンプレートが過負荷にならないという問題はありませんか?)。
これを受け入れるのは標準的な行動ですか?なぜ?
おまけの質問として、GCC がテンプレート パラメーターを std::initializer_list として推測するのを好まないのはなぜですか? コードをコピーして貼り付けて、パラメーターを std::initializer_list に置き換えるだけだと期待するのは、かなりばかげているようです。
警告メッセージ:
test.cpp: In function ‘int main()’:
test.cpp:33:43: warning: deducing ‘const list_t’ as ‘const std::initializer_list<int>’ [enabled by default]
test.cpp:6:6: warning: in call to ‘bool in_list(const elem_t&, const list_t&) [with elem_t = int, list_t = std::initializer_list<int>]’ [enabled by default]
test.cpp:33:43: warning: (you can disable this with -fno-deduce-init-list) [enabled by default]
から呼び出されたときin_list(3, {1, 2, 3, 4, 5});
編集: どうやらテンプレート パラメーターを initializer_list として推測することは、私のバージョンの GCC ( cite ) のワーキング ドラフトによる拡張です。新しい質問:これは最終的な c++11 標準の時点でまだ拡張機能ですか? もしそうなら、これは、標準に準拠したコードの 2 番目の関数を追加する必要があることを意味します。ご助力いただきありがとうございます!
EDIT2: GCC 4.7 ではコンパイラの方言フラグが削除されているように見えるため、問題は解決されたようですが、どのように解決されたかはわかりません。