是否有一种简单/智能的方法来实现缺少的运算符:‘operator+’ (operand types are ‘myclassRef<int>’ and ‘myclass<int>’)
这两个类?
我知道我可以定义一个将这两种类型作为参数的函数。
但是由于我正在实现几个应该同时使用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;
}
答案 0 :(得分:1)
没有必要使用内部类。相反,你应该构建两个全局运算符,它们存在于这两个类之外:
T operator+(const myclassRef<int>&, const myclass<int>&)
和重载
T operator+(const myclass<int>&, const myclassRef<int>&)
T
是您决定的返回类型。如果这些函数中的任何一个需要类中的私有数据,那么通过将这些声明放在类声明中,使函数成为两个类的friend
:
friend T operator+(const myclassRef<int>&, const myclass<int>&);
friend T operator+(const myclass<int>&, const myclassRef<int>&);
继续,您可能希望在myclassRef
类型上创建这些函数模板,尽管只有更现代的编译器支持将模板函数设为朋友。
答案 1 :(得分:0)
我使用template template
参数为我的问题找到了解决方案。这种方法允许我交替使用这两个类。但是,它需要对这两个类进行一些更改。对于myclassRef
,我必须添加const
版get()
并将myclass
设置为friend class
。对于myclass
,我必须定义一个新的构造函数,即myclass(const myclassRef<T>& 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;
}