繁体   English   中英

模板到C ++ 14中的模板映射

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM