range-v3
range-v3 copied to clipboard
Cannot easily use ref-qualified member functions as projections
This call fails to compile:
const auto it{ranges::find(values, stringToFind, &Value::value)};
with:
error: no match for call to '(const ranges::find_fn) (const std::vector<Value>&, const std::string&, <unresolved overloaded function type>)'
...
note: couldn't deduce template parameter 'V'
when member function value
has ref-qualified overloads:
[[nodiscard]] std::string value() &;
[[nodiscard]] const std::string &value() const& noexcept;
[[nodiscard]] std::string &&value() && noexcept;
I can make it work by using lambda as projection, or static_cast'ing member function to specific signature, but these solutions are too verbose and just loses the beauty of projections...
Full example here: https://godbolt.org/z/ddj5qE1EE
I guess it's "wontfix", but maybe there's is some magic template trickery to select best overload..?
This could work: https://godbolt.org/z/q4eTeM6dT.
It'd have to be properly integrated with projections. I haven't checked to see if that's possible. Projections already default to std::identity
, so overloading might be necessary. It could also be a breaking change for things convertible to a member pointer.
It would be nice to fix this.
Is this really a projection issue? This is just one example of part of a broader problem of passing overload sets into function templates.
I feel like this either requires a language feature to create the overload set, or a language feature to perform overload resolution during template deduction time to bind which overload you want (by going through the constraint somehow).
or a language feature to perform overload resolution during template deduction time to bind which overload you want
Like https://wg21.link/P1167?
or a language feature to perform overload resolution during template deduction time to bind which overload you want
Like https://wg21.link/P1167?
No, that's about class templates?
What I meant was something like:
template <class F> requires invocable<F, int const&, int const&>
void algo(F );
// this is ill-formed today, but we know we need to call this with (int const&, int const&)
// and those arguments do find a unique overload, so we could hypothetically pick it
algo(std::max);
I meant the part titled "Deduction guides for function templates".
I meant the part titled "Deduction guides for function templates".
I don't see how that's relevant either.
I supposed that could be used to solve the problem in the OP, but not necessarily the broader problem you describe.
I supposed that could be used to solve the problem in the OP, but not necessarily the broader problem you describe.
The problem in OP is passing an overloaded name into a function template, which can't deduce. Having function template deduction guides still requires deduction to have succeeded first.
That's true.
Sorry, I don't grok your discussion. Can it be fixed in Ranges library, or this needs new C++ language feature?
Any ideas how "deducing this" C++23 feature will help (or not)?
It will allow to write single template function for all ref-qualified overloads: https://youtu.be/b0NkuoUkv0M?t=188 (3:08).
As projections, they need to be treated like you would a template function.