2
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是依赖类。

解决方案是什么?

4

3 回答 3

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

在我看来,这是处理这种情况的最简单方法。

于 2012-06-25T10:11:06.797 回答
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;
    }
};
于 2012-06-25T15:30:03.370 回答
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);
}
于 2012-06-25T16:09:16.543 回答