[英]Template to template map in 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
我理解为什么它是假的: 它已在这里得到解答 。 基本上,该标准确保别名的模板实例化应该被识别为相同,但对模板本身没有任何说明。 因此,使用g ++ , std::is_same
为true,而使用clang ++ ,则为false。
我的问题是:如何使用g ++和clang ++实现模板映射,以满足std::is_same
要求? 我愿意用宏作为最后的手段......
一般来说,你所要求的等同于功能比较,它等同于停止问题,即不可计算。 然而...
如果您只想为某些特定的预定义模板执行此操作,则可以将它们专门用于标记类,然后可以在标记类上使用NeedsTemplate。 那是,
namespace Reflect {
struct Reflect {};
}
template<class T>
struct KeyType {};
namespace Reflect {
struct KeyType {};
}
template<>
struct KeyType<Reflect::Reflect> {
using type = Reflect::KeyType;
};
...然后使用KeyType<Reflect::Reflect>
,这是一种类型,而不是KeyType
,它是一个模板。 请注意,您仍然可以在界面上使用KeyType
(模板); 你只需要在反射上调用std::is_same<>
。 另请注意,这需要您为每种类型编写反射 - 虽然这对于宏来说是微不足道的。 此外,您不能将Reflect::Reflect
用作键类型。 (你可以通过特征以另一种方式做到这一点,但是你专注于特征的命名空间,这对于多个文件来说有点棘手。)
#define REFLECT_TEMPLATE(TEMPL) \
namespace Reflect { \
struct TEMPL {}; \
}; \
template<> \
struct TEMPL<Reflect::Reflect> { \
using type = Reflect::KeyType; \
};
如果我是你,我还会在反射类型中添加一个const char* name() const
...
不要将模板用作元编程原语。 使用类型。 类似,避免价值观。
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>;
你永远不会使用原始template
,只需ztemplate
s。
template<class T>
struct KeyType {};
using zKeyType=ztemplate<KeyType>;
C ++元编程在类型上更好用。 如果你想要对你的类型进行限制(比如它必须是一个ztemplate
),请编写SFINAE或ztemplate
的概念来强制执行它。
作为奖励, ztemplate
是定义模板的值 。 这让你开启了hana风格的元编程。
这意味着您必须规范地包装模板代码,并去除直接模板和值参数(分别替换为ztemplate和整型常量)。 但是你最终会得到更强大的元编程。
而不是X<Blah>
apply<zX, Blah>
。 实际上, apply
是您直接使用的唯一模板。
注意apply<zapply, zX, Blah>
并apply<zapply, zapply, zX, Blah>
等与apply<zX, Blah>
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.