2016-04-07 2 views
0

Consultez le code suivant:constructeur automatique et copie: quel est le problème?

#include<queue> 
#include<type_traits> 

int main() { 
    std::queue<int> q; 
    auto p{q}; 
    static_assert(std::is_same<decltype(q), decltype(p)>::value, "fail"); 
} 

Il compile très bien avec GCC 5.1.0 (voir here) et clang 3.8.0 (voir here), mais il n'a pas avec GCC 4.9. 0 (voir here). D'après une analyse plus poussée, il semble être dû au fait que le type de p est std::initializer_list.
À titre d'exemple, il fonctionne si l'on substitue la ligne:

auto p{q}; 

Avec la ligne:

decltype(q) p{q}; 

Je ne suis pas sûr que l'on est juste (même si GCC 5.1.0 fonctionne selon mes attentes) et c'est pourquoi j'ai demandé ici.
Est-il normal de s'attendre à ce que le type p soit std::queue<int>?

+0

Ceci est une situation exceptionnelle. Mayers a écrit à ce sujet dans le "C++ moderne efficace" pour C++ 11/14. Ceci est dû à une règle de déduction de type spéciale pour auto. Lorsque l'initialiseur d'une variable auto-déclarée est entouré d'accolades, le type déduit est une std :: initiale izer_list. Si un tel type ne peut pas être déduit (par exemple, parce que les valeurs dans le tializer bridé ini- sont de types différents) – arturx64

+0

auto est C++ 11 caractéristique et autant que je sache, il est entièrement pris en charge dans gcc seulement à partir de 5.1 – Peregrin

Répondre

0

N ° {q} est évalué à std::initializer_list. Il n'y a rien à dire au compilateur que vous pourriez vouloir quelque chose d'autre, alors Auto utilise celui-là.

Egalement decltype(q) n'est pas la même que decltype({q});