Fak*_*ker 1 c++ templates template-meta-programming
template <template <typename...> typename T, template <typename...> typename U>
struct is_same_template : std::false_type {};
template <template <typename...> typename T>
struct is_same_template<T, T> : std::true_type {};
template <template <typename...> typename T, template <typename...> typename U>
constexpr bool is_same_template_v = is_same_template<T, U>::value;
Run Code Online (Sandbox Code Playgroud)
上面的实现is_same_template可以导致下面的两条语句编译。
static_assert(is_same_template_v<std::map, std::map>);
static_assert(!is_same_template_v<std::map, std::vector>);
Run Code Online (Sandbox Code Playgroud)
是否可以增强is_same_template以下语句的编译能力?
static_assert(is_same_template_v<std::map<int, bool>, std::map>);
static_assert(is_same_template_v<std::map<int, bool>, std::map<int, int>>);
static_assert(!is_same_template_v<std::map<int, bool>, std::vector>);
static_assert(!is_same_template_v<std::map<int, bool>, std::vector<int>>);
Run Code Online (Sandbox Code Playgroud)
由于模板类的模板参数是固定的,所以不能定义一个同样命名is_same_template但接受不同模板参数的模板类,而是需要重新定义模板类但复用is_same_template,即使用模板部分特化来获取模板模板参数并将其传递给is_same_template.
template <typename T, typename U>
struct is_same_template2 : std::false_type {};
template<
template <typename...> typename T, typename... TArgs,
template <typename...> typename U, typename... UArgs>
struct is_same_template2<T<TArgs...>, U<UArgs...>> : is_same_template<T, U> {};
template <typename T, template <typename...> typename U>
struct is_same_template3 : std::false_type {};
template <
template <typename...> typename T, typename... TArgs,
template <typename...> typename U>
struct is_same_template3<T<TArgs...>, U> : is_same_template<T, U> {};
Run Code Online (Sandbox Code Playgroud)
为了统一接口,可以重载不同的模板函数,并使用相应的实现
template <template <typename...> typename T, template <typename...> typename U>
constexpr bool same_template() {
return is_same_template<T, U>();
}
template <typename T, typename U>
constexpr bool same_template() {
return is_same_template2<T, U>();
}
template <typename T, template <typename...> typename U>
constexpr bool same_template() {
return is_same_template3<T, U>();
}
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样调用
static_assert(same_template<std::map, std::map>());
static_assert(!same_template<std::map, std::vector>());
static_assert(same_template<std::map<int, bool>, std::map>());
static_assert(same_template<std::map<int, bool>, std::map<int, int>>());
static_assert(!same_template<std::map<int, bool>, std::vector>());
static_assert(!same_template<std::map<int, bool>, std::vector<int>>());
Run Code Online (Sandbox Code Playgroud)