2017-09-15 80 views
0

我掙扎明白,爲什麼我不能的typedef這個地圖,編譯器會抱怨這個編譯時間圖有什麼問題?

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; 

這裏是

#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; 
} 

看來,在某種程度上正在採取在地圖上的typedef的第一個關鍵的代碼作爲關鍵類型,我不確定這是怎麼發生的。

編輯

我來到了一個解決方案,我們的目標是有一些恆定值的類型編譯時間圖,這樣我就可以在編譯時映射到枚舉類型。我能夠通過將Key包裝到一個類型中,並將KeyType作爲第一個模板參數傳遞給地圖來解決問題。一些樣板類型定義使它不像template<int V> using IntMap = Map<MyKey<int, V>;template<MyEnum E> using MyEnumMap = Map<MyEnum, E>那樣難看。我相信這些可以使用C++ 17自動模板更清潔。請給出意見。

#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; 
} 

回答

0

Map的前向聲明預計只能看到類型參數。您正在專門化中使用非類型參數,這是不允許的。

這就是編譯器所抱怨的。

我無法提出解決方案,因爲我不知道你想用混合的類型和非類型參數來完成什麼。

+0

據我所知,從錯誤消息,但我的專業是'模板結構Map {'so爲什麼只是期待類型? – shane

+0

@shane,我更新了我的答案。希望這更有意義。 –

+0

我能夠通過將'KeyType,Key,Value'封裝在'template struct KeyValue {};''然後'Map'專用爲'template 來解決問題, KeyType Key,typename Value,typename..Rest> struct Map ,Rest ...> {};' – shane