0

次の基本構造のコードがあります。

namespace A{

    template<class T,unsigned DIM>
    class CMyTable{
        ...
            public:
            template<class T,unsigned DIM>
            friend std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec);
        }    

    };

}

最初の問題は、自分の operator<< を名前空間 A の外に出すことでした。

私はこの解決策を試しました:別のC++名前空間内のグローバル名前空間で友達を定義するにはどうすればよいですか?

namespace A{

    template<class T,unsigned DIM>
    class CMyTable;
}

template<class T,unsigned DIM>
std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec);

namespace A{

    template<class T,unsigned DIM>
    class CMyTable{
        ...
            public:
            template<class T,unsigned DIM>
            friend std::ostream& ::operator<<(std::ostream& s, const CMyTable<T,DIM>& vec);
        }    

    };

}

template<class T,unsigned DIM>
std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec){
// [...]
}

次のエラーが発生しました: エラー C2063: 'operator <<' : クラス宣言内の関数ではありません。

public:
template<class T,unsigned DIM>
friend std::ostream& ::operator<<(std::ostream& s, const CMyTable<T,DIM>& 

誰にもアイデアはありますか?

ありがとう。

4

2 に答える 2

0

出力演算子は実際にはクラスのインターフェイスであるため、論理的には、クラスが宣言されている名前空間にある必要がありますが、コードを機能させるために使用できます

namespace A{

    template<class T,unsigned DIM>
    class CMyTable;
}

// friend is not correct here.
template<class T,unsigned DIM>
/*friend*/ std::ostream& operator<<(std::ostream& s, const A::CMyTable<T,DIM>& vec);

namespace A{

    template<class T,unsigned DIM>
    class CMyTable{
        ...
            public:
            // choose another names of template pars.
            // or use
            //friend std::ostream& (::operator << <>)(std::ostream& s,
            //const CMyTable<T, DIM>&);
            /*template<class T,unsigned DIM>*/
            template<class U, unsigned D>
            friend std::ostream& (::operator <<)(std::ostream&,
            const CMyTable<U,D>&);
        };
}

template<class T,unsigned DIM>
std::ostream& operator<<(std::ostream& s, const A::CMyTable<T,DIM>& vec){
// [...]
}
于 2013-04-19T08:25:04.667 に答える
0

ostream オーバーロードがfriend(保護されたメンバーへのアクセスが必要) でなければならない場合は、インラインで定義して、クラスに渡されたテンプレート引数を使用できるようにします。

namespace A{

    template<class T,unsigned DIM>
    class CMyTable{
        ...
        public:
        // template<class T,unsigned DIM>  // This will shadow otherwise
        friend std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec) {
        // [...]
        }
    };
}

それ以外の場合は、クラスと名前空間からその宣言を完全に削除し、テンプレート化されたオーバーロードとして外部で定義するだけです。

プライベートまたは保護された要素へのアクセスが必要ない場合は、フレンドである必要はないことに注意してください。

namespace A{
   template<class T,unsigned DIM>
   class CMyTable{
    ...
        public:
    };
}



template<class T,unsigned DIM>
std::ostream& operator<<(std::ostream& s, const A::CMyTable<T,DIM>& vec){
// [...]
}

3 番目のオプションは、それをフレンドのままにして、名前空間 A 内で定義することです。

namespace A{

    template<class T,unsigned DIM>
    class CMyTable{
        public:
            int i;

        template<class V,unsigned E>
        friend std::ostream& operator<<(std::ostream& s, const CMyTable<V,E>& vec);
    };  

};
//
//

namespace A{

    template<class T,unsigned DIM>
    std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec) {
        s << vec.i;
    }

}
于 2013-04-19T08:35:03.363 に答える