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+ はゼロまたは 1 つの引数を取る必要があります」というメッセージが表示されます。右。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 に答える