如何创建一个多次使用一个值的宏,而不复制它? [英] How can I create a macro which uses a value multiple times, without copying it?

查看:89
本文介绍了如何创建一个多次使用一个值的宏,而不复制它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个宏,将一对分解为两个局部变量.如果它只是一个变量,我不想创建该对的副本,这将完成:

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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆