在 C++ 中,你能像比较类型那样比较模板吗?
In C++, can you compare templates the way you can compare types?
我有一个类似于 std::is_same
的模板比较器的想法。如果两个模板相同,那么至少给定模板参数的实例化是相同的。
template<template<class...> class LHS, template<class..> class RHS, class... S>
using is_same_template = std::is_same<LHS<S...>, RHS<S...>>::value;
有没有办法在没有 S...
的情况下比较 LHS
和 RHS
?我相信如果没有 S...
,比较器无论如何都必须在 S...
上实例化。如果它们是模板函数,我不希望能够比较它们,我需要比较它们的实例化。我的直觉是正确的吗?
您对类型或值采用的方法似乎同样适用于模板。前两行仅显示模板的用法,不需要 equals
或 tag
函数,也不需要提供的模板的任何参数。后两个从值中提取模板并对这些模板执行相同的测试。
#include <iostream>
template<class...> struct A {};
template<class...> struct B {};
template<template<class...> class S>
struct Tag;
template<template<class...> class S>
struct Tag {
template<template<class...> class T>
constexpr auto equals(Tag<T>) -> std::false_type { return {}; }
constexpr auto equals(Tag<S>) -> std::true_type { return {}; }
};
template<template<class...> class T, class... V>
Tag<T> tag(T<V...> const&) { return {}; }
template<class S, class T>
auto equals(S && s, T && t) -> decltype(tag(s).equals(tag(t))) { return {}; }
int main(int argc, const char *argv[]) {
using namespace std;
cout << Tag<A>{}.equals(Tag<A>{}) << "; " << Tag<A>{}.equals(Tag<B>{}) << endl;
// 1; 0
cout << Tag<B>{}.equals(Tag<A>{}) << "; " << Tag<B>{}.equals(Tag<B>{}) << endl;
// 0; 1
A<float> af;
A<double> ad;
B<int> bi;
B<char, char> bcs;
cout << equals(af, ad) << "; " << equals(af, bi) << endl;
// 1; 0
cout << equals(bi, ad) << "; " << equals(bi, bcs) << endl;
// 0; 1
}
I had an idea for a template comparator analogous to std::is_same. [...] Is there a way to compare LHS
and RHS
without S...
?
你可以从this page中std::is_same
的"possible implementation"中获取灵感,为模板写一个类似的模板
template <template <typename ...> class, template <typename ...> class>
struct is_tpl_same : public std::false_type
{ };
template <template <typename ...> class C>
struct is_tpl_same<C, C> : public std::true_type
{ };
你可以验证
static_assert( true == is_tpl_same<std::set, std::set>::value, "!" );
static_assert( false == is_tpl_same<std::vector, std::set>::value, "!" );
我有一个类似于 std::is_same
的模板比较器的想法。如果两个模板相同,那么至少给定模板参数的实例化是相同的。
template<template<class...> class LHS, template<class..> class RHS, class... S>
using is_same_template = std::is_same<LHS<S...>, RHS<S...>>::value;
有没有办法在没有 S...
的情况下比较 LHS
和 RHS
?我相信如果没有 S...
,比较器无论如何都必须在 S...
上实例化。如果它们是模板函数,我不希望能够比较它们,我需要比较它们的实例化。我的直觉是正确的吗?
您对类型或值采用的方法似乎同样适用于模板。前两行仅显示模板的用法,不需要 equals
或 tag
函数,也不需要提供的模板的任何参数。后两个从值中提取模板并对这些模板执行相同的测试。
#include <iostream>
template<class...> struct A {};
template<class...> struct B {};
template<template<class...> class S>
struct Tag;
template<template<class...> class S>
struct Tag {
template<template<class...> class T>
constexpr auto equals(Tag<T>) -> std::false_type { return {}; }
constexpr auto equals(Tag<S>) -> std::true_type { return {}; }
};
template<template<class...> class T, class... V>
Tag<T> tag(T<V...> const&) { return {}; }
template<class S, class T>
auto equals(S && s, T && t) -> decltype(tag(s).equals(tag(t))) { return {}; }
int main(int argc, const char *argv[]) {
using namespace std;
cout << Tag<A>{}.equals(Tag<A>{}) << "; " << Tag<A>{}.equals(Tag<B>{}) << endl;
// 1; 0
cout << Tag<B>{}.equals(Tag<A>{}) << "; " << Tag<B>{}.equals(Tag<B>{}) << endl;
// 0; 1
A<float> af;
A<double> ad;
B<int> bi;
B<char, char> bcs;
cout << equals(af, ad) << "; " << equals(af, bi) << endl;
// 1; 0
cout << equals(bi, ad) << "; " << equals(bi, bcs) << endl;
// 0; 1
}
I had an idea for a template comparator analogous to std::is_same. [...] Is there a way to compare
LHS
andRHS
withoutS...
?
你可以从this page中std::is_same
的"possible implementation"中获取灵感,为模板写一个类似的模板
template <template <typename ...> class, template <typename ...> class>
struct is_tpl_same : public std::false_type
{ };
template <template <typename ...> class C>
struct is_tpl_same<C, C> : public std::true_type
{ };
你可以验证
static_assert( true == is_tpl_same<std::set, std::set>::value, "!" );
static_assert( false == is_tpl_same<std::vector, std::set>::value, "!" );