Question

Je travaille sur du code en utilisant decltype dans CodeGear RAD Studio.J'ai essayé la solution naïve, qui ressemble à ceci :

int main(int, char**) {
    int i;
    int &ir = i;
    decltype((ir)) ir_clone = ir;
}

Bien sûr, cela ne parvient pas à compiler :Erreur interne du compilateur.Je soupçonne plutôt qu'il n'y a rien de particulièrement mal avec ce code et qu'il y a un bug du compilateur concernant les expressions de référence.(Soit dit en passant, g++ n'a aucun problème avec le code et le compile correctement.) Cela n'aide cependant pas à résoudre le problème, car la plate-forme n'est pas négociable.

Si, plus haut, j'avais écrit

    decltype(ir) ir_clone = ir; /* No extra parens */

il compile et fonctionne comme prévu.Cependant, le problème ne s'arrête pas là, car cela ne calcule pas correctement la constance de l'environnement.En particulier:

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& */

Si je n'utilise pas les parenthèses pour faire de l'argument une expression, je perds la constance de l'argument dont j'ai besoin.

Un autre outil que je peux utiliser sont des modèles simples, comme celui-ci :

template<class T> struct unref     { typedef T type; }
template<class T> struct unref<T&> { typedef T type; }

Cela me permet de supprimer la partie référence d'un type, en utilisant unref<int&>::type.

Ce que je n'arrive pas à comprendre, c'est comment rassembler tous ces outils pour obtenir une expression réussie correspondant au type dont j'ai besoin.Pour l'une des choses dont j'ai besoin, je travaille sur une macro généralisée qui fait "foreach".(Oui, je sais que Boost fait mieux.) Il doit gérer les scénarios suivants :

(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>

Jusqu'à présent, mes tentatives simples échouent :

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. */

Des idées pour me mettre sur la bonne voie ?J'espère qu'il me manque juste quelque chose de simple.Peut-être que j'aborde le problème sous le mauvais angle.

Était-ce utile?

La solution

Essayez de créer une expression différente, plus complexe, qui donne le même type que celui souhaité, par exemple :

decltype((void(), ir))

Je ne pourrais pas vous dire pourquoi cela corrige le problème, mais parfois une expression différente fera l'affaire.

Autres conseils

Vous pouvez utiliser std::remove_reference (voir http://en.cppreference.com/w/cpp/types/remove_reference).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top