Vorrei creare una macro che decomprimi una coppia in due variabili locali. Mi piacerebbe non creare una copia della coppia se è solo una variabile, che quest'anno avrebbe compiuto:Come posso creare una macro che usa un valore più volte, senza copiarlo?
#define UNPACK_PAIR(V1, V2, PAIR) \
auto& V1 = PAIR.first; \
auto& V2 = PAIR.second;
UNPACK_PAIR(one, two, x);
Tuttavia, mi piacerebbe anche di non valutare l'espressione è dato più volte, ad esempio, questo dovrebbe solo chiamare expensive_computation()
volta:
UNPACK_PAIR(one, two, expensive_computation());
Se lo faccio:
#define UNPACK_PAIR_A(V1, V2, PAIR) \
auto tmp = PAIR; \
auto& V1 = tmp.first; \
auto& V2 = tmp.second;
allora funziona per il caso expensive_computation()
, ma rende una copia nel caso x
. Se faccio:
#define UNPACK_PAIR_R(V1, V2, PAIR) \
auto& tmp = PAIR; \
auto& V1 = tmp.first; \
auto& V2 = tmp.second;
allora funziona nel caso x
senza fare una copia, ma non riesce nel caso expensive_computation()
. Se faccio:
#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;
Questi sia compilare ed eseguire, ma ho il sospetto che invocano un comportamento indefinito - Ho ragione a tale proposito? Inoltre, uno di questi avrebbe senso?
#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;
Esiste un modo per creare una macro che funziona per entrambi i casi d'uso - non copiare x
ancora, inoltre, non invocando un comportamento indefinito quando dato il risultato di una chiamata di un'espressione o una funzione?
* "? Questi sia compilare ed eseguire, ma ho il sospetto che invocano un comportamento indefinito - Ho ragione di quel" * Questo dipende dall'uso. Invoca UB per qualcosa come 'auto id = [] (auto && x) -> decltype (auto) {return decltype (x) (x); }; auto && tmp = id (5); ', ma non invoca UB per' auto && tmp = 5; '- questo ha a che fare con l'estensione della durata dei temporaries legati al riferimento. Hai ** bisogno ** di mantenere il valore 'V' vivo tramite la tua macro? 'auto tmp = V;' mantiene anche il suo valore in vita, a meno che non abbia un problema di durata interna. – dyp
@dyp: Sì, mi piacerebbe mantenere il valore in vita, senza doverne fare una copia (cosa che 'auto tmp = V' farebbe se avesse una variabile locale) – Claudiu
[This] (http://stackoverflow.com)/questions/9431487/cc-define-macro-inside-macro) potrebbe essere rilevante. –