Is there any way to shadow existing variables when destructuring a std::pair
? For example if I have the following functions defined:
#include <iostream>
#include <utility>
std::pair<int, int> returns_pair(int a, int b)
{
return std::make_pair(a * a, b * b);
}
void prints_two_variables(int a, int b)
{
std::cout << a << "\n" << b << "\n";
}
Then this main
function works fine, since I make new variables from the returned std::pair
:
int main()
{
int a = 2;
int b = 3;
auto [x, y] = returns_pair(a, b);
prints_two_variables(x, y);
return 0;
}
Output:
4 9
But I can't use the same variable names and shadow the existing variables, since this tries to actually declare them again:
int main()
{
int a = 2;
int b = 3;
auto [a, b] = returns_pair(a, b);
prints_two_variables(a, b);
return 0;
}
Error:
main.cpp: In function ‘int main()’: main.cpp:12:15: error: conflicting declaration ‘auto a’ auto [a, b] = returns_pair(a, b); ^ main.cpp:10:9: note: previous declaration as ‘int a’ int a = 2; ^ main.cpp:12:15: error: conflicting declaration ‘auto b’ auto [a, b] = returns_pair(a, b); ^ main.cpp:11:9: note: previous declaration as ‘int b’ int b = 3; ^
I tried also without the auto
, but that gave a totally different error:
int main()
{
int a = 2;
int b = 3;
[a, b] = returns_pair(a, b);
prints_two_variables(a, b);
return 0;
}
Error:
main.cpp: In lambda function: main.cpp:12:12: error: expected ‘{’ before ‘=’ token [a, b] = returns_pair(a, b); ^ main.cpp: In function ‘int main()’: main.cpp:12:31: error: no match for ‘operator=’ (operand types are ‘main()::’ and ‘std::pair’) [a, b] = returns_pair(a, b); ^ main.cpp:12:10: note: candidate: main()::& main()::::operator=(const main()::&) [a, b] = returns_pair(a, b); ^ main.cpp:12:10: note: no known conversion for argument 1 from ‘std::pair’ to ‘const main()::&’
Is there any way to accomplish this?
Is there any way to destructure a pair, while shadowing existing variables?
No. A structured binding declaration always introduces identifiers, it cannot shadow or assign over existing variables. This is ill-formed:
int i = 4;
auto [i] = std::tuple(5);
for the same reason this is ill-formed:
int i = 4;
int i = 5;
If what you want to do is overwrite, you can use tie
and assign:
std::tie(a, b) = returns_pair(a, b);
This works in this scenario, but not in the general case where returns_pair
might return a struct with two public members.
What you want is std::tie
. That will create a a std::tuple
of references to the parameters and allow you to reassign the pair
to the elements it was created from. That would look like
int main()
{
int a = 2;
int b = 3;
std::tie(a, b) = returns_pair(a, b);
prints_two_variables(a, b);
return 0;
}
Remember to also #include
the <tuple>
header so you can use std::tie
.
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