2016-07-16 5 views
0
#include <type_traits> 

template<typename T> 
T f(T&& a, T&& b) 
{ 
    return a + b; 
} 

template<typename T, typename... Args> 
T f(T&& a, T&& b, Args&&... args) 
{ 
    return f(a, f(b, std::forward<Args>(args)...)); 
} 

int main() 
{ 
    f(1, 2, 3); 
} 

VS 2015の出力:エラーC2672: 'F':なしマッチングオーバーロードされた関数が期待通りに動作しないのはなぜ再帰的バリデーションテンプレートが期待どおりに機能しないのはなぜですか?

を見つけましたか?

+0

template<typename T, typename U> typename std::decay<T>::type f(T&& a, U&& b) { return a + b; } template<typename T, typename U, typename... Args> typename std::decay<T>::type f(T&& a, U&& b, Args&&... args) { return f(std::forward<T>(a), f(std::forward<U>(b), std::forward<Args>(args)...)); } 

を、その後に簡略化することができましたか?コードには3つあります。 –

+2

ヒントg ++ 4.9.3では、次のエラーが表示されます。 test.cpp:10:3​​:注:テンプレート引数の控除/置換に失敗しました: test.cpp:12:49:注:パラメータ 'T'の競合するタイプを推定しました。 'int&'と 'int') return f(a、f(b、std :: forward (args)...)); – robal

+2

std :: forwardはで定義されていません robal

答えて

5

問題は、再帰的にa : intb : int&でバイナリオーバーロードを呼び出そうとし、その結果fを呼び出すときにabを転送していないことです。ここでは最初のステップです:

template<typename T> 
T f(T&& a, T&& b) { 
    return a + b; 
} 

template<typename T, typename... Args> 
T f(T&& a, T&& b, Args&&... args) { 
    return f(std::forward<T>(a), f(std::forward<T>(b), std::forward<Args>(args)...)); 
} 

今の問題は、渡されたすべての引数が同じ値のカテゴリを持っている必要がありますし、任意の左辺値の引数が、例えば、エラーの原因となることですint i = 2; f(1, i, 3);は失敗します。この問題を解決するには..:あなたがで問題が発生しているF` `への呼び出しの

template<typename T, typename U> 
typename std::decay<T>::type 
f(T&& a, U&& b) { 
    return a + b; 
} 

template<typename T, typename... Args> 
typename std::decay<T>::type 
f(T&& a, Args&&... args) { 
    return f(std::forward<T>(a), f(std::forward<Args>(args)...)); 
} 
+0

戻り値の型としてautoを使用する方が効果的です。 decay はUを気にしません。floatにintを追加すると(その順序で)、intではなくfloatが返されます。 –

+0

@EmilioGaravaglia:OPはすべてのタイプが同じであることを望んでいたので、異なるタイプをサポートするための私の答えには注意を払っていません。これを行うには複数のアプローチがありますが、 'C++ 11'というタグが付いているので、単に戻り値の型を' auto'にすることはその一つではありません。 : - [ – ildjarn

+0

はい...悲しいことに、C++ 0x/1x仕様からの大きなミス。 –

関連する問題