这个编译时间图有什么问题?

c++11 templates template-meta-programming

74 观看

1回复

714 作者的声誉

编译器抱怨,我正在努力理解为什么我不能对地图进行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;
 }

似乎以某种方式将map typedef中的第一个键用作键类型,但我不确定这种情况如何发生。

编辑

我提出了一个解决方案,目标是要有一个从某些常量值到类型的编译时间映射,这样我就可以在编译时将枚举映射到类型。我可以通过将Key封装为类型并将KeyType作为第一个模板参数传递给地图来解决该问题。一些样板typedef使它不像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;
 }
作者: shane 的来源 发布者: 2017 年 9 月 15 日

回应 1


0

178445 作者的声誉

MapExpect 的前向声明只能看到类型参数。您在专业化中使用非类型参数,这是不允许的。

这就是编译器所抱怨的。

我无法提出解决方案,因为我不知道混合类型和非类型参数将要完成什么。

作者: R Sahu 发布者: 2017 年 9 月 15 日
32x32