模板到C 14的模板地图

我想在C 14中为模板映射做一个模板.先验,似乎以下代码可以解决这个问题

template<class T>
struct KeyType {};

template<class T>
struct ValueType {
    T x;
};

template<template<class> class K>
struct Map;

template<>
struct Map<KeyType> {
    template<class T>
    using type = ValueType<T>;
};

ValueType<int> test{42};
Map<KeyType>::type<int> testM{42}; // Same as above

但是,使用clang v3.8编译时,以下表达式返回false.

template<template<class> class TemplateType>
struct NeedsTemplate;

std::is_same<
    NeedsTemplate<ValueType>,
    NeedsTemplate<Map<KeyType>::type>
>::value; // False

我理解为什么它是错误的:it has already been answered here.基本上,该标准确保别名的模板实例化应该被识别为相同,但是对模板它们自身没有任何说明.因此,对于g,std :: is_same为true,而对于clang,则为false.

我的问题是:如何使用g和clang实现模板映射,以满足std :: is_same要求?我愿意用宏作为最后的手段……

最佳答案 不要将模板用作元编程原语.使用类型.类似,避免价值观.

template<template<class...>class Z>
struct ztemplate{
  template<class...Ts>
  using apply=Z<Ts...>;
};
template<class Z, class...Ts>
using apply=typename Z::template apply<Ts...>;
using zapply=ztemplate<apply>;

你从不使用原始模板,只是ztemplates.

template<class T>
struct KeyType {};
using zKeyType=ztemplate<KeyType>;

C元编程在类型方面效果更好.如果你想要对你的类型进行限制(比如它必须是一个ztemplate),请编写SFINAE或伪造的概念来强制执行它.

作为奖励,ztemplate是定义模板的值.这让你开启了hana风格的元编程.

这意味着您必须规范地包装模板代码,并去除直接模板和值参数(分别替换为ztemplate和整型常量).但是你最终会得到更强大的元编程.

而不是X< Blah>应用< zX,Blah>.实际上,apply是您直接使用的唯一模板.

注意适用< zapply,zX,Blah>并应用< zapply,zapply,zX,Blah> etc与apply< zX,Blah>相同.

点赞