【发布时间】:2017-09-15 04:31:18
【问题描述】:
我很难理解为什么我不能 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;
}
【问题讨论】:
标签: c++11 templates template-meta-programming