Template for template in C ++ 14

I want to create a template for a template in C ++ 14. A priori, it seems the following code does the trick

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

However, the following expression when compiling with clang ++ v3.8 returns false.

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

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

I understand why this is not true: the answer has already been given here . Basically, the standard ensures that template instances of aliases should be recognized as the same thing, but it says nothing about templates. Therefore, with g ++ , it std::is_sameis true, and with clang ++ it is false.

My question is: how can I implement a template for a template that will satisfy the requirements with std::is_sameboth g ++ and clang ++? I am ready to use a macro as a last resort ...

+4
2

. . , .

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>;

raw template s, ztemplate s.

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

++ . , (, ztemplate), SFINAE psuedo-concept .

ztemplate - , . .

, ( ztemplate ). .

X<Blah> do apply<zX, Blah>. , apply , .

apply<zapply, zX, Blah> apply<zapply, zapply, zX, Blah> .. , apply<zX, Blah>.

+1

, , , , , .. . ...

, , , 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 ...

+1

Source: https://habr.com/ru/post/1666189/


All Articles