如何创建一个多次使用一个值的宏,而不复制它? [英] How can I create a macro which uses a value multiple times, without copying it?
问题描述
我想创建一个宏,将一对分解为两个局部变量.如果它只是一个变量,我不想创建该对的副本,这将完成:
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);
但是,我也希望它不评估多次给出的表达式,例如这应该只调用一次expensive_computation()
:
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());
如果我这样做:
#define UNPACK_PAIR_A(V1, V2, PAIR) \
auto tmp = PAIR; \
auto& V1 = tmp.first; \
auto& V2 = tmp.second;
然后适用于expensive_computation()
情况,但是会复制x
情况.如果我这样做:
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;
然后它可以在x
情况下工作而不进行复制,但是在expensive_computation()
情况下会失败.如果我这样做:
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;
有什么方法可以创建适用于这两种用例的宏-不复制x
,而且在给出表达式或函数调用的结果时也不会调用未定义的行为?
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?
推荐答案
auto&&
创建转发引用,即它接受任何内容.它不会(总是)创建右值引用.因此,只需执行以下操作:
auto&&
creates a forwarding reference, i.e. it accepts anything. It does not (always) create an rvalue reference. So just do this:
#define UNPACK_PAIR(V1, V2, PAIR) \
auto&& tmp = PAIR; \
auto& V1 = tmp.first; \
auto& V2 = tmp.second;
但是,我强烈建议不要这样做(除非UNPACK_PAIR
的使用范围非常有限,并且该操作在该范围内确实无处不在).看起来晦涩难懂,对我没有任何实际好处.想象一下,六个月后返回项目,仅两个小时就找到了一个严重的错误.您是否要感谢您使用非标准的基于宏的语法而不是易读的内容?
However, I would strongly suggest against this (unless the scope of the use of UNPACK_PAIR
is very limited and the operation is really ubiquitous in that scope). It looks like obscurity for no real benefit to me. Imagine returning to the project after 6 months, with just two hours to find a critical bug. Will you be thanking yourself for using a nonstandard macro-based syntax instead of something readable?
这篇关于如何创建一个多次使用一个值的宏,而不复制它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!