使用 CRTP 从模板类集继承运算符

问题描述

这是 this Q/A 的后续内容

我正在通过使用 template <template<typename> class C,typename T> 而不是我在问题答案中显示的示例来听取用户 Jarod42 的建议。

我的代码目前是这样的:

template<template<typename> class C,typename T>
struct single_member_ops {
    friend auto operator+(const C<T>& lhs,const C<T>& rhs) 
    { return lhs.value + rhs.value; }
    friend auto operator+(const C<T>& lhs,const T& rhs)
    { return lhs.value + rhs;}
    friend auto operator+(const T& lhs,const C<T>& rhs)
    { return lhs + rhs.value;}

    friend auto operator+=(const C<T> & lhs,const C<T> & rhs) {
        C<T> temp;
        temp.value = lhs.value + rhs.value;
        return temp.value;
    }

    friend auto operator+=(const C<T>& lhs,const T& rhs ) {
        C<T> temp;
        temp.value = lhs.value + rhs;
        return temp.value;
    }

    friend auto operator+=(const T& lhs,const C<T>& rhs) {
        C<T> temp;
        temp.value = lhs + rhs.value;
        return temp.value;
    }

};

template<typename T>
struct A : public single_member_ops<A<T>,T>{
    T value;    
    A() = default;
    explicit A(T in) : value{in} {}
    explicit A(A<T>& in) : value{in.value} {}
    auto& operator=(const A<T>& rhs) { return value = rhs; }
    auto& operator=(const T& rhs) { return value = rhs; }
};

template<typename T>
struct B : public single_member_ops<B<T>,T> {
    T value;
    B() = default;
    explicit B(T in) : value{in} {}
    explicit B(B<T>& in) : value{in.value} {}
    auto& operator=(const B<T>& rhs) {return value = rhs;}
    auto& operator=(const T& rhs) { return value = rhs; }
};

int main() {
    A<int> a1(4);
    A<int> a2;
    A<int> a3{0};
    a2 = 6;
    a3 = a1 + a2; 

    B<int> b1(5);
    B<int> b2(7); 

    B<double> bd1(3.4);
    B<double> bd2(4.5); 

    auto x1 = a1 + a2;
    auto x2 = a1 + b2;
    auto x3 = b1 + bd1;
    //auto y1 = a2 - b2;
    //auto y2 = b2 - a1;

    A<int> z;
    z += a2 + a3;

    return z.value;
}

您可以在 Compiler Explorer

上看到它

我仅显示 +()+=() 运算符以减少显示代码量。我希望我的所有运算符都在此基类 single_member_ops 中定义,并成为将从该基类派生的所有类的朋友。

我上面的代码示例为未为定义的二元运算符定义相关运算符的行生成编译器错误

auto x2 = a1 + b2;
auto x3 = b1 + bd1;

看来我可以将 +()+=() 运算符用于所有在类及其类型中都匹配的类型,例如 A<int> 和 {{1 }} 这很好。但是,假设我想互换使用它们,例如在以下伪情况下:

A<int>

我需要做什么,或者我的操作员会是什么样子来实现这一目标?我还缺少什么?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)