3

I have a std::vector of std::typle:

std::vector<std::tuple<int,int>> vt;

And I can transform the content of the vector to an other vector, by the algorithm std::transform, like this:

std::vector<int> vi(vt.size());

std::transform( vt.begin(), vt.end(), vi.begin(), [](auto &v) -> int {
    return std::get<0>(v);
} );   

Of course I could use a function too:

int myget(const std::tuple<int,int>& t)
{
    return std::get<0>(t);
}

std::vector<int> vi(vt.size());
std::transform( vt.begin(), vt.end(), vi.begin(), myget );


But would it be possible to use std::get directly, as a actual parameter in std::transform?

I mean somthing like this:

std::transform( vt.begin(), vt.end(), vi.begin(), std::get<0, ??? > );
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • There might be some convoluted syntax to get a pointer to an instantiated instance of the `std::get` template function, and pass this pointer, as a callable object, to `std::transform`. If one is found, it would surely come with a sense of accomplishment, and a pat on one's back, for successfully navigating C++'s insanely complicated syntax. But don't labor under a myth that you've accomplished anything substantive because, in the end, it's a near certainty that the compiler will generate substantively identical code, and all you've really done is wrote an undecipherable stream of punctuation. – Sam Varshavchik Nov 25 '17 at 15:58

1 Answers1

4

Yes, it is possible, but I wouldn't recommend it at all. Because std::get has multiple overloads, you need to static_cast to the right one.

static_cast<int&(*)(std::tuple<int, int>&)>(&std::get<0, int, int>)

Really, that's not nice to look at, with repetition of template arguments two times. And if you want the cast to be generic, it will be pretty long.

Instead, to shorten your lambda, you can drop the -> int, as the return type will get automatically deduced:

std::transform( vt.begin(), vt.end(), vi.begin(), [](auto &v) {
    return std::get<0>(v);
} );

Someday, we might be able to write this:

std::transform(vt.begin(), vt.end(), vi.begin(), [](auto &v) => std::get<0>(v));
Rakete1111
  • 47,013
  • 16
  • 123
  • 162