I'd like to create a macro which unpacks a pair into two local variables. I'd like to not create a copy of the pair if it's just a variable, which this would accomplish:
#define UNPACK_PAIR(V1, V2, PAIR) \
auto& V1 = PAIR.first; \
auto& V2 = PAIR.second;
UNPACK_PAIR(one, two, x);
However, I'd also like it to not evaluate the expression it's given multiple times, e.g. this should only call expensive_computation()
once:
UNPACK_PAIR(one, two, expensive_computation());
If I do:
#define UNPACK_PAIR_A(V1, V2, PAIR) \
auto tmp = PAIR; \
auto& V1 = tmp.first; \
auto& V2 = tmp.second;
then it works for the expensive_computation()
case, but it makes a copy in the x
case. If I do:
#define UNPACK_PAIR_R(V1, V2, PAIR) \
auto& tmp = PAIR; \
auto& V1 = tmp.first; \
auto& V2 = tmp.second;
Then it works in the x
case without making a copy but fails in the expensive_computation()
case. If I do:
#define UNPACK_PAIR_CR(V1, V2, PAIR) \
const auto& tmp = PAIR; \
auto& V1 = tmp.first; \
auto& V2 = tmp.second;
#define UNPACK_PAIR_RR(V1, V2, PAIR) \
auto&& tmp = PAIR; \
auto& V1 = tmp.first; \
auto& V2 = tmp.second;
These both compile and run, but I suspect they invoke undefined behavior - am I correct about that? Also, would either of these make any sense?
#define UNPACK_PAIR_RR(V1, V2, PAIR) \
auto&& tmp = std::move(PAIR); \
auto& V1 = tmp.first; \
auto& V2 = tmp.second;
#define UNPACK_PAIR_RR(V1, V2, PAIR) \
auto&& tmp = std::forward<decltype(PAIR)>(PAIR); \
auto& V1 = tmp.first; \
auto& V2 = tmp.second;
Is there any way to create a macro that works for both of these use cases - not copying x
yet also not invoking undefined behavior when given the result of an expression or function call?
You don't need a macro for this.
auto p = std::make_pair(2, 3);
int x, y;
std::tie(x, y) = p;
If you want references to existing members of a pair:
auto p = std::make_pair(2, 3);
auto& x = p.first;
auto& y = p.second;
That's it.
Now you can move on to something more challenging/interesting/important.
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