Reputation: 28438
My intention is to write a getter for the N
th element of whatever std::get
can take as argument once it's instantiated with a specific N
.
In other words, std::get<N>
cannot be passed around because it's not a function object, but a function templated on the type of the argument it takes.
Is it possible to define an object getNth
such that std::invoke(getNth<1>, whatever);
makes sense and is actually equivalent to getNth<1>(whatever)
?
The most I could get working is std::invoke(getNth<1>(), whatever);
, by defining getNth
this way:
template<int N>
auto getNth() {
return [](auto const& x){ return std::get<N>(x); };
};
Is it possible to avoid having to use the two parenthesis?
I thought templated lambdas could be useful, but they can't as they are classes with a templated operator()
just like generic non-templated lambdas (with only difference that with the former we can have the type of the parameters be non-identity functions of the template parameters).
Instead, for std::invoke(getNth<1>, whatever);
to be meaningful, I think getNth
should not be a template function, nor a template class, but something else... which doesn't take parenthesis after the closing >
, as it happens for variable templates.
However, based on the bullet point at the top of this page, probably I'm looking for something which the syntax simply does not offer. Is this the case?
Upvotes: 2
Views: 209
Reputation: 157394
which doesn't take parenthesis after the closing
>
, as it happens for variable templates.
Exactly, a variable template is just what you want:
#include <functional>
#include <tuple>
template<int N>
auto getNth = [](auto const& x){ return std::get<N>(x); };
int main() {
auto whatever = std::tuple{1, 2, 3};
return std::invoke(getNth<1>, whatever);
}
Upvotes: 5