【问题标题】:Modelling a symmetric relation of types like (std::plus,std::minus) with templates possible?可以使用模板对(std::plus,std::minus)等类型的对称关系进行建模吗?
【发布时间】:2020-08-17 00:45:20
【问题描述】:

是否可以在 c++(20) 中定义(无序的)类型对,以允许通过在编译时提供其任何成员来找到这样的对?

这很容易通过手动为每个无序对定义两个有序对或通过在一个位置定义完整的对集合来实现,例如作为元组的模板参数:

通过特化定义对 (A,B):

template<>
struct find_pair<A> {
    using p = std::pair<A,B>;
};

template<>
struct find_pair<B> {
    using p = std::pair<A,B>;
};

获取(A,B):

find_pair<A>::p

find_pair<B>::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>

方法#1 的优点是对的每个定义都可以分开,但需要冗余/臃肿的语法。 方法 #2 要求每种类型只编写一次,但必须手动收集模板参数列表中的所有对(不灵活)。

有没有可能以某种方式做到这一点?对定义可以彼此分开 并且一对定义中不需要重复代码?

当然,没有两个不同的对必须包含相同的类型,并且不必支持搜索不存在的对。

【问题讨论】:

    标签: c++ templates template-meta-programming


    【解决方案1】:

    不确定您实际在寻找什么,但这可能有用:

    #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>()));
    

    自定义点:在pair命名空间中声明函数Pair&lt;Type1, Type2&gt; RegisterPair(Pair&lt;Type1, Type2&gt;)

    然后使用FindPair 元函数查找类型对:

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

    【讨论】:

      猜你喜欢
      • 2022-08-12
      • 2022-01-02
      • 2017-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-30
      • 2014-04-18
      • 1970-01-01
      相关资源
      最近更新 更多