Reputation: 22570
Is there a way to write a variant of std::tie
in C++ that ties deeply into a tuple. That is, one in which tie((x,y),z) = make_tuple(make_tuple(1,2),3)
binds x, y, z
to 1, 2 and 3
, respectively as in the following example.
#include <tuple>
#include <iostream>
using namespace std;
int main() {
int x, y ,z;
auto t = make_tuple(1,2);
std::tie(y,x)= t;
//std::tie((x,y),z) = make_tuple(t,3); //not working
cout << x << y << z << endl;
return 0;
}
Upvotes: 3
Views: 1537
Reputation: 35469
You can go:
std::forward_as_tuple(std::tie(x, y), z) = std::make_tuple(t, 3);
std::forward_as_tuple
works very similarly to std::tie
, except that unlike it it will not reject std::tie(x, y)
as an argument.
Upvotes: 7
Reputation:
Maybe you're looking for std::tuple_cat
:
std::tie(x,y,z) = std::tuple_cat(t, make_tuple(3));
You can string together tuples
as one long tuple, to avoid dealing with nested tuples. I think the solution to flattening nested tuples would be more complex.
Just to make a clarification on how std::tie
works (I think). std::tie
constructs a tuple of lvalue references from its arguments. When you use the assignment operator, copy assignments are performed. std::tie((x,y),z)
doesn't do what you think. You're subjecting (x,y)
to the comma operator, where x is discarded. There is no magic going on, where nesting is determined by parentheses. If one of the arguments to std::tie
is a tuple, then the corresponding argument should be a tuple as well. i.e.: std::tie(tuple, 3) = std::make_tuple(std::make_tuple(1, 2), 3)
. However this is not what you want, which is where my suggestion comes from, because it doesn't seem like your intention is to flatten a nested tuple.
Upvotes: 6