GCC 4.7.2とClang 3.1の両方でC++ 11コードをコンパイルしている間に、Clangがテンプレート引数を推論するのに問題が発生しました。 GCCは成功する。より抽象的な形で は、コードは次のようになります。テンプレートパラメータとしてのVariadicテンプレート:GCCではなく、Clangではなく
のsrc/test.cc:
struct Element {
};
template <typename T>
struct FirstContainer {
};
template <typename T, typename U = Element>
struct SecondContainer {
};
template <template <typename> class Container>
void processOrdinary(Container<Element> /*elements*/) {
}
template <template <typename, typename> class Container>
void processOrdinary(Container<Element, Element> /*elements*/) {
}
template <template <typename, typename...> class Container>
void processVariadic(Container<Element> /*elements*/) {
}
int main() {
// This function instantiation works in both GCC and Clang.
processOrdinary(FirstContainer<Element>{});
// This function instantiation works in both GCC and Clang.
processOrdinary(SecondContainer<Element>{});
// This function instantiation works in both GCC and Clang.
processVariadic(FirstContainer<Element>{});
// This function instantiation works in both GCC and Clang.
processVariadic<SecondContainer>(SecondContainer<Element>{});
// This function instantiation works in GCC but not in Clang.
processVariadic(SecondContainer<Element>{});
return 0;
}
を標準の§14.8.2に§14.3.3の例と仕様を読んでから、私は控除がうまくいくはずだとは思いますが、私は確かに言えません。これは建物から得られる出力です:
mkdir -p build-gcc/
g++ -std=c++0x -W -Wall -Wextra -Weffc++ -pedantic -c -o build-gcc/test.o src/test.cc
g++ -o build-gcc/test build-gcc/test.o
mkdir -p build-clang/
clang++ -std=c++11 -Weverything -Wno-c++98-compat -c -o build-clang/test.o src/test.cc
src/test.cc:34:3: error: no matching function for call to 'processVariadic'
processVariadic(SecondContainer<Element>{});
^~~~~~~~~~~~~~~
src/test.cc:21:6: note: candidate template ignored: failed template argument deduction
void processVariadic(Container<Element> /*elements*/) {
^
1 error generated.
make: *** [build-clang/test.o] Fel 1
なぜ結果は異なりますか?私のコードには不特定の動作やそのすべてが含まれていますか?クランは、この呼び出しの引数を推測しようとしている
私はあなたに同意します。私がC++ 11最終草案で見たことは、これがうまくいくはずだということです。 14.3.3.3が特に適切です。 –
あなたの例題に 'typedef int element;'がありません。 – Quuxplusone
いいえ、コードの冒頭に、Elementという名前の構造体を定義します。 – psyill