2017-04-02 12 views
3

cppreferenceから、std::apply(add_generic, ...)への呼び出しがコンパイルに失敗する理由を教えてください。それを修正する方法はありますか?エラーとstd :: applyが汎用関数で失敗するのはなぜですか?

#include <iostream> 
#include <tuple> 

int add(int first, int second) 
{ 
    return first + second;  
} 

template<typename T> 
T add_generic(T first, T second) 
{ 
    return first + second;  
} 

int main() 
{ 
    std::cout << std::apply(add, std::make_tuple(1,2)) << '\n'; 

    // template argument deduction/substitution fails 
    std::cout << std::apply(add_generic, std::make_tuple(2.0f,3.0f)) << '\n'; 
} 

それはfails

[x86-64 gcc 7 (snapshot)] error: no matching function for call to 'apply(, std::tuple)' [x86-64 gcc 7 (snapshot)] note: couldn't deduce template parameter '_Fn'

+0

何を得るのエラーを見なければ、私はそれができたのですよね引数型 'T'を適切に推論できないためですか? –

+0

コードをどのようにコンパイルしていますか? 'std :: apply'は' C++ 17'を必要とします、あなたのコンパイラは 'C++ 17'をサポートしていますか? – Rogus

+3

'add_generic'は関数ではなく、テンプレートです。タイプを持たないものからタイプを推論することはできません。 – chris

答えて

8

これはC++ 17には新しいものではありません。 std::applyの署名から、add_generic<int>add_generic<float>add_generic<std::string>、またはそれ以外のものを渡すかどうかはわかりません。より多くの文脈が必要であることがわかっている(具体的には、std::applyがそれを呼び出す方法を知る必要があります)が、その情報はコールサイトでは利用できないため、テンプレート引数の控除には使用できません。

それはオブジェクトを渡し、そしてadd_genericのいずれかのインスタンスを呼び出すことのできる一つのオブジェクトが必要であるとすることによってことを回避することが可能です:

std::cout << std::apply(
    [](auto first, auto second) { return add_generic(first, second); }, 
    std::make_tuple(2.0f,3.0f)) << '\n'; 
関連する問題