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
的使用范围非常有限,并且该操作在该范围内真的无处不在).它看起来默默无闻,对我没有真正的好处.想象一下,在 6 个月后回到项目,只需要两个小时就可以找到一个严重的错误.你会感谢自己使用非标准的基于宏的语法而不是可读的东西吗?
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?
这篇关于如何创建一个多次使用一个值而不复制它的宏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何创建一个多次使用一个值而不复制它的宏?


基础教程推荐
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01