template <class T>
class A {
struct B {
T a,b;
}
B& operator+ (B & x, B & y) {
return B(x.a + y.a, x.b + y.b);
}
int funcA (B & x, B & y){
return (x + y).a;
}
};
正如您可能猜到的,在编译期间,我得到“operator +必须采用零或一个参数”。 对。因为在运算符+中,“this”作为第一个参数传递。 因此,解决方案是将运算符定位在A类定义之外。 但是A的函数funcA使用operator +。所以它必须在A之前定义。但是operator +本身使用A中定义的B类,它是模板本身,B是依赖类。
解决方案是什么?
答案 0 :(得分:3)
有一种方法可以在类的主体内定义一个自由函数:
struct B {
T a,b;
// the change from B& to B is nothing to do with defining
// the function here, it's to avoid returning a dangling reference.
friend B operator+ (B & x, B & y) {
return B(x.a + y.a, x.b + y.b);
}
};
对我来说,这是处理这种情况的最简单方法。
答案 1 :(得分:0)
除了@ SteveJessop的答案 - 这是最好的答案 - 如果运营商要成为会员,则必须是B
的成员,而不是A
的成员:
template <typename T>
class A {
public:
struct B {
T a,b;
B(const T& x, const T& y) : a(x), b(y) {}
B operator+(const B& rhs) const { return B(a + rhs.a, b + rhs.b); }
};
T funcA (B & x, B & y){
return (x + y).a;
}
};
答案 2 :(得分:0)
您可以将声明operator+
转发到A
之外,但funcA
必须明确调用它。对于这种情况,您可能不希望在operator+
之外定义A
,但是因为您已经问过
因此,解决方案是将运算符定位在A类定义之外。 ......怎么样?
这个答案说明了它是怎么回事。
与molbdnilo一样,我也同意Steve Jessop的答案是最好的,这是你应该对这个问题采取的答案。
template <class T> class A;
template <class T>
typename A<T>::B operator + (typename A<T>::B &x, typename A<T>::B &y);
template <class T>
class A {
template <class U>
friend typename A<U>::B operator + (typename A<U>::B &x,
typename A<U>::B &y);
struct B {
T a,b;
B(T x, T y) : a(x), b(y) {}
};
static T funcA (B & x, B & y) {
return ::operator+<T>(x, y).a;
}
public:
A () {
B a(0, 1);
B b(1, 0);
funcA(a, b);
}
};
template <class T>
typename A<T>::B operator + (typename A<T>::B &x,
typename A<T>::B &y) {
return typename A<T>::B(x.a + y.a, x.b + y.b);
}