为什么std :: apply失败了泛型函数?

Ben*_*oît 5 c++ c++17

cppreference中获取,为什么调用std::apply(add_generic, ...)无法编译?有办法解决吗?

#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'; 
}
Run Code Online (Sandbox Code Playgroud)

失败并出现错误:

[x86-64 gcc 7(快照)]错误:没有匹配函数调用'apply(,std :: tuple)'[x86-64 gcc 7(快照)]注意:无法推导出模板参数'_Fn'

小智 11

这在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';
Run Code Online (Sandbox Code Playgroud)