C++ 使用模板对(std::plus,std::minus)等类型的对称关系建模是否可能?
是否可以在c++(20)中定义(无序的)类型对,以允许在编译时通过提供其任何成员来查找此类类型对 通过手动为每个无序对定义两个有序对,或在一个位置定义完整的对集(例如,作为元组的模板参数),可以实现这一点: 通过专门化定义对(A,B):C++ 使用模板对(std::plus,std::minus)等类型的对称关系建模是否可能?,c++,templates,template-meta-programming,C++,Templates,Template Meta Programming,是否可以在c++(20)中定义(无序的)类型对,以允许在编译时通过提供其任何成员来查找此类类型对 通过手动为每个无序对定义两个有序对,或在一个位置定义完整的对集(例如,作为元组的模板参数),可以实现这一点: 通过专门化定义对(A,B): template<> struct find_pair<A> { using p = std::pair<A,B>; }; template<> struct find_pair<B> {
template<>
struct find_pair<A> {
using p = std::pair<A,B>;
};
template<>
struct find_pair<B> {
using p = std::pair<A,B>;
};
模板
结构查找对{
使用p=std::pair;
};
模板
结构查找对{
使用p=std::pair;
};
得到(A,B):
find_pair::p
或
find_pair::p
通过可变模板定义整套配对:
template<typename A, typename B, typename ... X>
struct some_binary_relation : some_binary_relation<X...> {
template<>
static std::pair<A,B> p<A>();
template<>
static std::pair<A,B> p<B>();
};
using rel1 = some_relation<A,B,F,G,M,N>;
decltype(rel1::p<G>()) x //std::pair<F,G>
模板
构造一些二元关系:一些二元关系{
模板
静态std::pair p();
模板
静态std::pair p();
};
使用rel1=某些_关系;
decltype(rel1::p())x//std::pair
方法#1的优点是一对的每个定义都可以分开,但需要冗余/臃肿的语法。
方法#2要求每个类型只写入一次,但必须手动收集模板参数列表中的所有对(不灵活)
有没有可能以s.t.的方式实现这一点?这对定义可以彼此分开
在对定义中不需要重复代码
当然,没有两个不同的对必须包含相同的类型,并且不必支持搜索不存在的对。不确定您实际查找的是什么,但这可能很有用:
#include <utility>
namespace pair {
template<class T> struct Type {};
template<class A, class B>
struct Pair {
Pair(Type<A>);
Pair(Type<B>);
using type = std::pair<A, B>;
};
} // pair
namespace detail {
void FindPairImpl(...);
template<class A>
auto FindPairImpl(pair::Type<A> a) -> typename decltype(RegisterPair(a))::type;
} // namespace detail
template<class PairedType>
using FindPair = decltype(detail::FindPairImpl(pair::Type<PairedType>()));
template<typename A, typename B, typename ... X>
struct some_binary_relation : some_binary_relation<X...> {
template<>
static std::pair<A,B> p<A>();
template<>
static std::pair<A,B> p<B>();
};
using rel1 = some_relation<A,B,F,G,M,N>;
decltype(rel1::p<G>()) x //std::pair<F,G>
#include <utility>
namespace pair {
template<class T> struct Type {};
template<class A, class B>
struct Pair {
Pair(Type<A>);
Pair(Type<B>);
using type = std::pair<A, B>;
};
} // pair
namespace detail {
void FindPairImpl(...);
template<class A>
auto FindPairImpl(pair::Type<A> a) -> typename decltype(RegisterPair(a))::type;
} // namespace detail
template<class PairedType>
using FindPair = decltype(detail::FindPairImpl(pair::Type<PairedType>()));
namespace pair { auto RegisterPair(Pair<double, const char *> a) -> decltype(a); }
int main() {
static_assert(std::is_same<FindPair<int>, void>::value);
static_assert(std::is_same<FindPair<double>, std::pair<double, const char *>>::value);
static_assert(std::is_same<FindPair<const char *>, std::pair<double, const char *>>::value);
}