2017-09-15 9 views
0

J'ai du mal à comprendre pourquoi je ne peux pas typedef cette carte, le compilateur se plaintQuel est le problème avec cette carte de temps de compilation?

main.cpp:14:41: error: type/value mismatch at argument 1 in template 
parameter list for 'template<class ...> struct Map' 
struct Map<KeyType, Key, Value, Rest...> { 
            ^
main.cpp:14:41: note: expected a type, got 'Key' 
main.cpp:24:23: error: type/value mismatch at argument 1 in template 
parameter list for 'template<class ...> struct Map' 
typedef Map<int, 1, A> map; 

Voici le code

#include <type_traits> 
#include <iostream> 

template<typename...> 
struct Map; 

template<typename KeyType> 
struct Map<KeyType> { 
    template<KeyType NotFound> 
    struct get { typedef std::false_type val; }; 
}; 

template<typename KeyType, KeyType Key, typename Value, typename... Rest> 
struct Map<KeyType, Key, Value, Rest...> { 
    template<KeyType Get> 
    struct get { 
     typedef std::conditional<Get == Key, Value, typename Map<KeyType, Rest...>::template get<Get>::val> val; 
    }; 
}; 

struct A { static constexpr int value = 1; }; 
struct B { static constexpr int value = 2; }; 

typedef Map<int, 1, A> map; 

int main() { 
    std::cout << map::get<1>::val::value << std::endl; 
    //std::cout << map::get<2>::val::value << std::endl; 
    //std::cout << map::get<3>::val::value << std::endl; 
} 

Il semble que en quelque sorte la première clé sur la carte typedef est prise comme le type de clé, et je ne suis pas sûr de savoir comment cela se passe.

EDIT

Je suis venu à une solution, l'objectif est d'avoir une carte de compilation d'une certaine valeur constante à un type, donc je peux mapper énumérations à des types au moment de la compilation. J'ai été capable de résoudre le problème en enveloppant la clé dans un type, et en passant le KeyType en tant que premier paramètre de modèle à la carte. Certaines typedefs passe-partout le rendent pas aussi laid que template<int V> using IntMap = Map<MyKey<int, V>; et template<MyEnum E> using MyEnumMap = Map<MyEnum, E>. Je crois que ceux-ci pourraient être rendus plus propres en utilisant des modèles automatiques C++ 17. Commentez s'il vous plaît.

#include <type_traits> 
#include <iostream> 

template<typename KeyType, KeyType Key> 
struct KeyValue {}; 

struct KeyNotFound {}; 

template<typename...> 
struct Map; 

template<typename KeyType> 
struct Map<KeyType> { 
    template<KeyType Key> 
    struct get { typedef KeyNotFound type; }; 
}; 

template<typename KeyType, KeyType Key, typename Value, typename... Rest> 
struct Map<KeyType, KeyValue<KeyType, Key>, Value, Rest...> { 
    template<KeyType Get> 
    struct get { 
     typedef typename std::conditional<Get == Key, Value, typename Map<KeyType, Rest...>::template get<Get>::type>::type type; 
    }; 
}; 

struct A { static constexpr int value = 1; }; 
struct B { static constexpr int value = 2; }; 


typedef Map<int, 
    KeyValue<int, 1>, A, 
    KeyValue<int, 2>, B> map; 

int main() { 
    std::cout << map::get<1>::type::value << std::endl; 
    //std::cout << map::get<2>::val::value << std::endl; 
    //std::cout << map::get<3>::type::value << std::endl; 
} 

Répondre

0

La déclaration avant de Map s'attend à voir uniquement les paramètres de type. Vous utilisez un paramètre non-type dans la spécialisation, ce qui n'est pas autorisé.

C'est ce dont se plaint le compilateur.

Je ne suis pas en mesure de proposer une solution car je ne sais pas ce que vous essayez d'accomplir avec une combinaison de paramètres de type et de non-type.

+0

Je comprends cela à partir du message d'erreur, mais ma spécialisation est 'template struct Map {' pourquoi est-ce que seuls les types attendent? – shane

+0

@shane, j'ai mis à jour ma réponse. J'espère que cela a plus de sens. –

+0

J'ai été capable de résoudre le problème en enveloppant 'KeyType, Key, Value' dans un' template struct KeyValue {}; 'puis la speacialization' Map' est 'template struct Map , Rest ...> {}; ' – shane