C++ 不同c+之间运算符的简单实现+;班级

C++ 不同c+之间运算符的简单实现+;班级,c++,operators,C++,Operators,是否有一种简单/智能的方法来实现缺少的运算符:'operator+'(操作数类型为'myclassRef'和'myclass')? 我知道我可以定义一个函数,将这两种类型作为参数。 但是,由于我正在实现几个函数,这些函数应该以myclass和myclassRef类型作为参数,因此我希望以一种简单的方式来实现 我一直在研究将myclassRef作为myclass的一个内部类,并使用隐式转换,但是这种方法(据我所知)要求所有使用这两种类型作为参数的函数都是成员函数 #include <iost

是否有一种简单/智能的方法来实现缺少的运算符:
'operator+'(操作数类型为'myclassRef'和'myclass')
? 我知道我可以定义一个函数,将这两种类型作为参数。 但是,由于我正在实现几个函数,这些函数应该以
myclass
myclassRef
类型作为参数,因此我希望以一种简单的方式来实现

我一直在研究将
myclassRef
作为
myclass
的一个内部类,并使用隐式转换,但是这种方法(据我所知)要求所有使用这两种类型作为参数的函数都是成员函数

#include <iostream>
using namespace std;

template <class T>
struct myclass;

template <class T>
struct myclassRef
{
    T* i;

    myclassRef(myclass<T>* A)
    {
        i = &A->i;
    }

    operator myclass<T>()
    {
        return myclass<T>(*i);
    }

    T& get()
    {
        return *i;
    }
};

template <class T>
struct myclass
{
    T i;

    myclass() = default;
    myclass(const myclass&) = default;
    myclass(T _i) : i(_i) {}

    myclassRef<T> ref()
    {
        return myclassRef<T>(this);
    }

    T& get()
    {
        return i;
    }

    T get() const
    {
        return i;
    }
};

template <class T>
myclass<T>& operator+=(myclass<T>& lhs, const myclass<T>& rhs)
{
    lhs.get() += rhs.get();
    return lhs;
}

template <class T>
myclass<T> operator+(const myclass<T>& lhs, const myclass<T>& rhs)
{
    myclass<T> res(lhs);
    res += rhs;
    return res;
}

int main() {
    myclass<int> A(5);
    myclass<int> B(2);

    auto C = A + B;

    std::cout << C.i << std::endl;

    auto D = C.ref();

    A = D + B;

    return 0;
}
#包括
使用名称空间std;
模板
结构myclass;
模板
结构myclassRef
{
T*i;
myclassRef(myclass*A)
{
i=&A->i;
}
运算符myclass()
{
返回myclass(*i);
}
T&get()
{
返回*i;
}
};
模板
结构myclass
{
TⅠ;
myclass()=默认值;
myclass(常量myclass&)=默认值;
myclass(T_i):i(_i{}
myclassRef ref()
{
返回myclassRef(此);
}
T&get()
{
返回i;
}
T get()常量
{
返回i;
}
};
模板
myclass和运算符+=(myclass和lhs、常量myclass和rhs)
{
lhs.get()+=rhs.get();
返回lhs;
}
模板
myclass运算符+(常量myclass和lhs、常量myclass和rhs)
{
myclass res(lhs);
res+=rhs;
返回res;
}
int main(){
甲级(5);
myclass B(2);
自动C=A+B;

std::cout不需要使用内部类。相反,您应该构建两个全局运算符,它们存在于两个类之外,如下所示:

T operator+(const myclassRef<int>&, const myclass<int>&)

接下来,您可能希望在
myclassRef
类型上创建这些函数模板,尽管只有更现代的编译器支持与模板函数交朋友。

我使用
template-template
参数为我的问题找到了一个解决方案。这种方法允许我互换这两个类。但是,我t需要对这两个类进行一些更改。对于
myclassRef
我必须添加
get()
const
版本,并将
myclass
设置为
friend class
。对于
myclass
我必须定义一个新的构造函数,即
myclass(const myclassRef&r)
。当然,还要更改这两个运算符的参数

更改是在代码中标记的

#include <iostream>
using namespace std;

template <class T>
struct myclass;

template <class T>
struct myclassRef
{
    T* i;

    myclassRef(myclass<T>* A)
    {
        i = &A->i;
    }

    T& get()
    {
        return *i;
    }

    T get() const // Added as part of the answer
    {
        return *i;
    }

    friend class myclass<T>; // Added as part of the answer
};

template <class T>
struct myclass
{
    T i;

    myclass() = default;
    myclass(const myclass&) = default;
    myclass(T _i) : i(_i) {}
    myclass(const myclassRef<T>& r) : i(*r.i) {} // Added as part of the answer

    myclassRef<T> ref()
    {
        return myclassRef<T>(this);
    }

    T& get()
    {
        return i;
    }

    T get() const
    {
        return i;
    }
};

template <template <class> class Mlhs, template <class> class Mrhs, class T>  // Added as part of the answer
Mlhs<T>& operator+=(Mlhs<T>& lhs, const Mrhs<T>& rhs)
{
    lhs.get() += rhs.get();
    return lhs;
}

template <template <class> class Mlhs, template <class> class Mrhs, class T>  // Added as part of the answer
myclass<T> operator+(const Mlhs<T>& lhs, const Mrhs<T>& rhs)
{
    myclass<T> res(lhs);
    res += rhs;
    return res;
}

int main() {
    myclass<int> A(5);
    myclass<int> B(2);

    auto C = A + B;

    std::cout << C.i << std::endl;

    auto D = C.ref();

    A = D + B;

    std::cout << A.i << std::endl;

    return 0;
}
#包括
使用名称空间std;
模板
结构myclass;
模板
结构myclassRef
{
T*i;
myclassRef(myclass*A)
{
i=&A->i;
}
T&get()
{
返回*i;
}
T get()const//作为答案的一部分添加
{
返回*i;
}
friend类myclass;//作为答案的一部分添加
};
模板
结构myclass
{
TⅠ;
myclass()=默认值;
myclass(常量myclass&)=默认值;
myclass(T_i):i(_i{}
myclass(constmyclassref&r):i(*r.i){}//作为答案的一部分添加
myclassRef ref()
{
返回myclassRef(此);
}
T&get()
{
返回i;
}
T get()常量
{
返回i;
}
};
模板//作为答案的一部分添加
Mlhs和操作员+=(Mlhs和lhs、常量Mrhs和rhs)
{
lhs.get()+=rhs.get();
返回lhs;
}
模板//作为答案的一部分添加
myclass运算符+(常量Mlhs和lhs、常量Mrhs和rhs)
{
myclass res(lhs);
res+=rhs;
返回res;
}
int main(){
甲级(5);
myclass B(2);
自动C=A+B;

std::我想没有办法做到这一点。但是有几个函数将这两种类型混合作为参数,这有点混乱。但如果你知道我的意思,至少它是一个“包含的混乱”。
friend T operator+(const myclassRef<int>&, const myclass<int>&);
friend T operator+(const myclass<int>&, const myclassRef<int>&);
#include <iostream>
using namespace std;

template <class T>
struct myclass;

template <class T>
struct myclassRef
{
    T* i;

    myclassRef(myclass<T>* A)
    {
        i = &A->i;
    }

    T& get()
    {
        return *i;
    }

    T get() const // Added as part of the answer
    {
        return *i;
    }

    friend class myclass<T>; // Added as part of the answer
};

template <class T>
struct myclass
{
    T i;

    myclass() = default;
    myclass(const myclass&) = default;
    myclass(T _i) : i(_i) {}
    myclass(const myclassRef<T>& r) : i(*r.i) {} // Added as part of the answer

    myclassRef<T> ref()
    {
        return myclassRef<T>(this);
    }

    T& get()
    {
        return i;
    }

    T get() const
    {
        return i;
    }
};

template <template <class> class Mlhs, template <class> class Mrhs, class T>  // Added as part of the answer
Mlhs<T>& operator+=(Mlhs<T>& lhs, const Mrhs<T>& rhs)
{
    lhs.get() += rhs.get();
    return lhs;
}

template <template <class> class Mlhs, template <class> class Mrhs, class T>  // Added as part of the answer
myclass<T> operator+(const Mlhs<T>& lhs, const Mrhs<T>& rhs)
{
    myclass<T> res(lhs);
    res += rhs;
    return res;
}

int main() {
    myclass<int> A(5);
    myclass<int> B(2);

    auto C = A + B;

    std::cout << C.i << std::endl;

    auto D = C.ref();

    A = D + B;

    std::cout << A.i << std::endl;

    return 0;
}