我想在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>相同.