template<typename T1, size_t SIZE>
void foo(std::vector<std::array<T1, SIZE>> bar) {
std::cout << "SPECIFIC (array)" << std::endl;
}
のstd::size_t
代わりに使用する必要がありますint
。
ここを走る
編集:
実際、あなたのコメントとコードに関する私の直感が私をトピックに掘り下げました。一見したところ、(私のような)標準的な開発者は、コンパイラint
がstd::size_t
(両方とも整数型であり、暗黙的に変換するのは非常に簡単であるため)に変換しvoid foo(std::vector<std::array<T1, SIZE>> bar)
、最適な特殊化として選択することを期待しています。だからテンプレート引数の控除ページを読んでいるときに私はこれを見つけました:
非タイプテンプレートパラメータがパラメータリストで使用され、対応するテンプレート引数が推定される場合、推定テンプレート引数のタイプ(そのテンプレートテンプレートリストで指定されているとおり、参照が保持されることを意味します)は、 cv-qualifiersが削除されていること、およびテンプレートの引数が配列の境界から推定される場合を除いて、正確に非型テンプレートパラメーター。この場合、整数型は許可され、ブール値であっても常にtrueになります。
もちろん、いつものように、それが何を意味するかを理解するために、一度よりも数回読む必要があります:)
だから面白い結果が出てきます。
必要な特殊化はすでに選択されていませんが、コンパイラーが強制的に選択した場合はエラーになります。
template<typename T1, int SIZE>
void foo(std::vector<std::array<T1, SIZE>> bar) {
std::cout << "SPECIFIC (array)" << std::endl;
}
int main() {
std::vector<std::array<int, 3>> b(2, std::array<int, 3> {4, 5, 6});
foo(b); // P = std::vector<std::array<int,(int)SIZE>
// A = std::vector<std::array<int,(unsigned_long)SIZE>>
// error: deduced non-type template argument does not have the same
// type as its corresponding template argument */
}
コードを実行する
別の興味深いことは次のとおりです。
非型テンプレート引数が推定されなかった場合、引数とテンプレート型を強制的に同じにする制限はありません。
#include <vector>
#include <array>
#include <iostream>
template<typename T1, int SIZE>
void foo(std::vector<std::array<T1, SIZE>> bar) {
std::cout << "SPECIFIC (array)" << std::endl;
}
int main() {
std::vector<std::array<int, 3>> b(2, std::array<int, 3> {4, 5, 6});
foo<int,3>(b);
}
コードを実行する
vector
すべてのアウターを削除することで、同じ問題でこれを簡略化できます。ここを参照