这个编译时间图有什么问题?
问题描述:
我挣扎明白,为什么我不能的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;
}
答
Map
的前向声明预计只能看到类型参数。您正在专门化中使用非类型参数,这是不允许的。
这就是编译器所抱怨的。
我无法提出解决方案,因为我不知道你想用混合的类型和非类型参数来完成什么。
据我所知,从错误消息,但我的专业是'模板结构Map {'so为什么只是期待类型? –
shane
@shane,我更新了我的答案。希望这更有意义。 –
我能够通过将'KeyType,Key,Value'封装在'template struct KeyValue {};''然后'Map'专用为'template 来解决问题, KeyType Key,typename Value,typename..Rest> struct Map ,Rest ...> {};' –
shane