2016-10-25 2 views
1
#include "stdafx.h" 
#include <iostream> 

#include <vector> 
#include <map> 

template <typename T> 
auto Copy(T c) 
{ 
    std::vector<decltype(c.begin()->first)> lc; 

    //Copying 

    return lc; 

} 

int main() 
{ 
    std::map<int, int> map; 

    Copy(map); 


    return 0; 
} 

Dans le code ci-dessus, je suis en train de déclarer un vector du type de données de clés de map mais je reçois l'erreur suivante -déclare un vecteur par decltype

"The C++ Standard forbids containers of const elements allocator<const T> is ill-formed." 
+0

Que pensez-vous du type de 'decltype (c.begin() -> en premier)' est, et pourquoi? – hvd

+2

Il est peut-être plus simple d'utiliser 'typename T :: key_type' au lieu de' decltype (...) ', si vous savez que' T' aura toujours un membre 'key_type', comme' std :: map' ou ' std :: unordered_map'. –

Répondre

4

Le problème est que decltype(c.begin()->first) retourne un const int(lors de l'utilisation libstdC++ - votre exemple compile avec libC++).

Comme votre erreur vous dit ...

La norme C++ interdit les conteneurs d'éléments const parce allocateur < const T> est mal formé.

Une solution utilise std::decay_t:

std::vector<std::decay_t<decltype(c.begin()->first)>> lc; 

Cela garantira que votre exemple fonctionne aussi bien avec libstdC++ et libC++. Alternativement, std::remove_const_t fonctionne également dans cette situation particulière.

Voici un working example on wandbox.

+2

La clé requise pour être 'const' n'est-elle pas requise? Je me demande pourquoi il n'y a pas de problème avec 'libC++'. – user2079303

+1

À un moment donné, il suffit d'utiliser le typedef 'key_type' au lieu de ce désordre compliqué. @ user2079303 C'est toujours 'const int'. C'est juste que libC++ arrive à être implémenté de telle façon que le 'vecteur 'ne soit pas aussi facile à faire exploser. –

+1

'decay_t' au lieu de' remove_const_t', car votre objectif est d'obtenir un type approprié pour le stockage, et 'decay_t' fait exactement cela? – Yakk