Come posso usare Decrtype per ottenere il tipo di riferimento?
-
12-11-2019 - |
Domanda
Sto lavorando su un codice utilizzando Decrtype in CodeGear Rad Studio. Ho provato la soluzione ingenua, che non sembra diversa da questa:
int main(int, char**) {
int i;
int &ir = i;
decltype((ir)) ir_clone = ir;
}
Naturalmente, questo non riesce a compilare: errore del compilatore interno. Preferisco sospetto che non ci sia nulla di particolarmente sbagliato in quel codice e che esiste un bug del compilatore per quanto riguarda le espressioni di riferimento. (Per inciso, G ++ non ha problemi con il codice e lo compila bene.) Ciò non aiuta a risolvere il problema, tuttavia, poiché la piattaforma non è negoziabile.
Se, sopra, avevo scritto
decltype(ir) ir_clone = ir; /* No extra parens */
Compila e funziona come previsto. Tuttavia, il problema non finisce qui, dal momento che ciò non calcola correttamente la costine dall'ambiente. In particolare:
struct S { int i; } s;
const S* p = &s;
decltype(p->i) i0 = s.i; /* i0 is an int */
decltype((p->i)) i1 = s.i; /* i1 is a const int& */
Se non uso i parenti per rendere l'argomento un'espressione, perdo la costine dell'argomento, di cui ho bisogno.
Un altro strumento che posso usare sono modelli semplici, come così:
template<class T> struct unref { typedef T type; }
template<class T> struct unref<T&> { typedef T type; }
Ciò mi permette di spogliare la parte di riferimento di un tipo, usando unref<int&>::type
.
Quello che non riesco a capire è come mettere insieme tutti questi strumenti per ottenere un'espressione di successo per il tipo di cui ho bisogno. Per una delle cose di cui ho bisogno, sto lavorando a una macro generalizzata che fa "foreach". (Sì, so che Boost lo fa meglio.) Deve gestire i seguenti scenari:
(vector<int>) vi => vector<int>
(vector<int>&)vir => vector<int>
(const vector<int>) cvi => const vector<int>
(const vector<int>&)cvir => const vector<int>
(const P*) cp->vi => const vector<int>
(P*) p->vi => vector<int>
Finora, i miei semplici tentativi falliscono:
unref<decltype(cp->vi)> /* is vector<int>, not what I need. */
unref<decltype((cp->vi))> /* is const vector<int>, which is right. */
unref<decltype(vir)> /* is vector<int>, which is right. */
unref<decltype((vir))> /* Internal Compiler Error, which is a headache. */
Qualche idea per portarmi sulla strada giusta? Spero che ci sia qualcosa di semplice che mi manca. Forse sto attaccando il problema dall'angolazione sbagliata.
Soluzione
Prova a fare un'espressione diversa e più complessa che si traduce nello stesso tipo che desideri, come ad esempio:
decltype((void(), ir))
Non potrei dirti perché lo risolve, ma a volte un'espressione diversa farà il trucco.
Altri suggerimenti
Puoi usare std :: remow_reference (vedi http://en.cppreference.com/w/cpp/types/remove_reference).