为什么 std::apply 会因泛型函数而失败?

Why does std::apply fail with a generic function?

取自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'; 
}

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'

这在 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';