Why std :: apply fail with a generic function?

Taken from cppreference , why is the call std::apply(add_generic, ...)

failing to compile? Is there a way to fix this?

#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'; 
}

      

It fails with error:

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

+3


source to share


1 answer


This is not new in C ++ 17. Just from the signature std::apply

, you do not know whether you want to transfer add_generic<int>

, add_generic<float>

, add_generic<std::string>

or anything else. Knowing this requires more context (in particular: it requires knowing how it std::apply

is going to call it), but this information is not available at the calling site and therefore cannot be used to derive the template argument.

You can work around this by passing one object and making one object callable, depending on which instance add_generic

you need:



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

      

+8


source







All Articles