Simple example:
std::vector<std::string> strings{"1","2","3");
std::vector<double> doubles(3);
transform(begin(strings), end(strings), begin(doubles), std::stod);
This fails to compile because the compiler cannot decide which std::stod
to use. The one that takes an std::string
or the one that takes an std::wstring
. We see that only one would work given how std::transform
works, but the compiler doesn't.
Options (bad ones)
std::stod<std::string>
because std::stod
is not a template but an overload. And even if it was a template, it would have to be a class template with a static non-templated function: Stod<std::string>::stod
.[](std::string const& s) { return std::stod(s); }
but that is quite a lot of code for nothing.double (*)(std::string const&)
) but to do that, I have to know the return type. For std::stod
that is simple, because it always returns a simple double
but for other functions that might be a very complicated thing to write down.Is there a more concise way than the lambda to select the correct overload or trick the compiler into figuring it out itself?
As you already know, you either resolve the overload upfront by casting, i.e. choosing one of the overloads, or you delay the overload resolution by wrapping the call in a function object (being it a lambda or something else).
The quickest way to take the latter approach, without writing any code of yours, is Boost.Hof's BOOST_HOF_LIFT
.
So instead of passing this
std::stod
you pass this
BOOST_HOF_LIFT(std::stod)
Isn't it concise enough?
(Working example on Compiler Explorer.)
static_cast<double(*)(const std::string&, std::size_t*)>(std::stod)
std::stod
requires 2 arguments. The default value for the argument doesn't tag along with the function pointer you give to transform
to work with.std::stod
is not one of them).The simplest solution for all is to package it in a lambda:
std::transform(std::begin(strings), std::end(strings), std::begin(doubles),
[](const std::string& s) { return std::stod(s); });
Is there a more concise way than the lambda to select the correct overload or trick the compiler into figuring it out itself?
No, none that is portable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With