5

次のコードを検討してください。

#include <iostream>
#include <type_traits>

// Variadic version
template<class... Variadic>
void f(const Variadic&... variadic)
{
    std::cout<<"variadic"<<std::endl;
}

// Single version
template<class Single, class = typename std::enable_if<std::is_fundamental<Single>::value>::type>
void f(const Single& single)
{
    std::cout<<"single"<<std::endl;
}

// Main
int main()
{
    f();              // variadic
    f(42);            // single : why?
    f(std::string()); // variadic 
    f(42, 42);        // variadic
    return 0;
}

「single」とマークされた行が(g ++ 4.6.3で)うまくコンパイルされ、オーバーロード解決の問題が発生しない理由がわかりません。c ++ 11標準では、パラメーターの数が固定されたテンプレート関数が、同じ署名を持つ可能性のある可変個引数関数よりも優先されるとされていますか?

4

2 に答える 2

5

それは本当に 非常に単純です(2つのライブ例、gccとclang)

template<class...T> void foo(T&&...) {std::cout << "...T\n";}
template<class T> void foo(T&&) {std::cout << "T\n";}
int main() {
  foo(3);
}

...選択が明示的なテンプレートパラメータである場合、オーバーロードを行わない方が好ましいようです。

これclass=std::enable_if_tは変更されません。

したがって、両方の関数fが候補である場合、コンパイラーは変数のないものを優先します。

14.8.2.4半順序付け中のテンプレート引数の推定[temp.deduct.partial]

/ 8:

関数Aパラメーターパックから変換され、パラメーターパックでPはない場合、型の推定は失敗します。それ以外の場合は、結果のタイプPとを使用してA、で説明されているように控除が行われ14.8.2.5ます。Pが関数パラメーターパックの場合A、引数テンプレートの残りの各パラメータータイプのタイプが、関数パラメーターパックの宣言子IDのタイプPと比較されます。各比較は、関数パラメーターパックによって展開されたテンプレートパラメーターパック内の後続の位置のテンプレート引数を推定します。特定の型に対して推論が成功した場合、引数テンプレートからの型は、少なくともパラメーターテンプレートからの型と同じくらい特殊化されていると見なされます。[ 例:

template<class... Args> void f(Args... args); // #1
template<class T1, class... Args> void f(T1 a1, Args... args); // #2
template<class T1, class T2> void f(T1 a1, T2 a2); // #3
f(); // calls #1
f(1, 2, 3); // calls #2
f(1, 2); // calls #3; non-variadic template #3 is more
// specialized than the variadic templates #1 and #

特に、f(1,2)例。

節が行うのは、asenable_if_tを渡すときに1つの引数のバージョンを検討対象から削除することだけです。std::stringT

于 2014-09-11T14:17:51.063 に答える
2

'single'バージョンで2番目のenable_ifテンプレートパラメーターを使用しているため、コンパイラーは、そのバージョンを、それが有効になっているタイプで使用するためのより特殊なテンプレートであると見なします。
可変個引数テンプレートをインスタンス化できるタイプがありますが、「シングル」はインスタンス化できないため、より特殊化されていると見なされます。

一般的なルールは、過負荷の解決において、より専門的なテンプレートがあまり専門的でないテンプレートよりも優先されるということです。

于 2013-01-06T09:07:17.497 に答える