Я хотел бы создать макрос, который распаковывает пару на две локальные переменные. Я хотел бы, чтобы не создать копию пары, если это просто переменная, это будет выполнять:Как создать макрос, который использует значение несколько раз, без копирования?
#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
пока также не вызывая неопределенное поведение, когда дали результата выражения или функции вызова?
* «? Это как скомпилировать и запустить, но я подозреваю, что они вызывают неопределенное поведение - я правильно о том, что» * Это зависит от использования. Он вызывает UB для чего-то вроде «auto id = [] (auto && x) -> decltype (auto) {return decltype (x) (x); }; auto && tmp = id (5); ', но он не вызывает UB для' auto && tmp = 5; '- это связано с расширением времени жизни временных привязок к ссылке. Вам ** нужно **, чтобы сохранить значение 'V' через ваш макрос? 'auto tmp = V;' также сохраняет свое значение в живых, если только у него нет внутренней проблемы с продолжительностью жизни. – dyp
@ dyp: Да, я хотел бы сохранить значение в живых, не делая его копии (что 'auto tmp = V' будет делать, если задана локальная переменная) – Claudiu
[This] (http://stackoverflow.com/questions/9431487/cc-define-macro-inside-macro) может иметь значение. –