我想创建一个宏,将一对解包成两个局部变量。如果它只是一个变量,我不想创建该对的副本,这将完成:
#define UNPACK_PAIR(V1, V2, PAIR) \
auto& V1 = PAIR.first; \
auto& V2 = PAIR.second;
UNPACK_PAIR(one, two, x);
但是,我也希望它不计算多次给出的表达式,例如这应该只调用expensive_computation()
一次:
UNPACK_PAIR(one, two, expensive_computation());
如果我做:
#define UNPACK_PAIR_A(V1, V2, PAIR) \
auto tmp = PAIR; \
auto& V1 = tmp.first; \
auto& V2 = tmp.second;
然后它适用于expensive_computation()
案例,但它会在案例中制作副本x
。如果我做:
#define UNPACK_PAIR_R(V1, V2, PAIR) \
auto& tmp = PAIR; \
auto& V1 = tmp.first; \
auto& V2 = tmp.second;
然后它可以在x
没有复制的情况下在案例中工作,但在expensive_computation()
案例中失败。如果我做:
#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;
这些都可以编译和运行,但我怀疑它们会调用未定义的行为——我对此是否正确?另外,这些中的任何一个都有意义吗?
#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;
有没有办法创建一个适用于这两种用例的宏——x
在给出表达式或函数调用的结果时,既不复制也不调用未定义的行为?