2011-08-01 21 views
3

演算子のオーバーロードに問題があります< <と名前空間を組み合わせました。私は、次のコードはOKコンパイル..演算子のオーバーロード<<ネームスペース対

を、関連記事を読みましたが、それでも私の場合で何が起こっているのか理解していない:

ファイルtest_matrix.hpp:

#ifndef TEST_MATRIX_HPP 
#define TEST_MATRIX_HPP 

#include <boost/numeric/ublas/matrix.hpp> 
#include <boost/numeric/ublas/matrix_expression.hpp> 
namespace ublas = boost::numeric::ublas; // shortcut name 

namespace VecMat { 
    typedef ublas::matrix<double> MatrixD; // matrix of doubles 

    template<class MT> 
    std::ostream & operator<< (std::ostream & os, 
           const ublas::matrix_expression<MT> & M) 
    { 
     // Note: the matrix_expression<MT> has only one method "()", which 
     // returns "& MT" or "const & MT" - a ref. to the included matrix object. 
     typename MT::const_iterator1 it1; 
     typename MT::const_iterator2 it2; 
     for (it1 = M().begin1(); it1 != M().end1(); ++it1) { 
      for (it2 = it1.begin(); it2 != it1.end(); ++it2) { 
       os << *it2 << "\t"; 
      } 
     os << std::endl; 
     } 
     return os; 
    } 
}; // namespace VecMat 
#endif 

ファイルtest_operを。 CPP:はVecMatを使用していること

#include "test_matrix.hpp" 
using std::cout; 
using std::endl; 
using VecMat::MatrixD; 
using VecMat::operator<<; 

// --------------------------------------------------------------------------- 
// would be in a header file 
void test1(); 
namespace Main { 
    void test2(); 
} 
// --------------------------------------------------------------------------- 

void test1() 
{ 
    MatrixD X(10,3); 
    VecMat::operator<<(cout << endl, X) << endl; 
    cout << "X =" << endl << X << endl; 
} 

void Main::test2() 
{ 
    MatrixD X(10,3); 
    VecMat::operator<<(cout << endl, X) << endl; 
    cout << "X =" << endl << X << endl; 
} 

注::演算子< <。ラインが必要とされている - それなしで、私はTEST1(の最後の行にエラーが発生します)(GCC 4.5を使用して):引数があるので、

test_oper.cpp||In function 'void test1()':|
test_oper.cpp|22|error: no match for 'operator<<' in '((std::basic_ostream*)std::operator<<

コンパイラは、ADLを使用して、オペレータの自己を見つけるべきではありませんタイプVecMat :: MatrixD

ファイルtest_other.hpp:私はその後、場合

#ifndef TEST_OTHER_HPP 
#define TEST_OTHER_HPP 
#include <ostream> 

namespace Main { 
    class Foo { 
     int n; 
    }; 
    std::ostream & operator<< (std::ostream & os, Foo const & foo); 
} 
#endif 

「私はメイン名前空間に独自のオペレータ< <で新しいクラスを追加するとき

私の主な問題は、しかし、開始します#include "test_other.hpp" 2つの元のファイルのいずれかから.cppファイルは、上記と同じエラーで、最後の行のでコンパイルされません。test2()

私は別の名前空間( VecMatか、または新しいのいずれか)にはFoo を置く場合

test_oper.cpp||In function 'void Main::test2()':| test_oper.cpp|29|error: no match for 'operator<<' in '((std::basic_ostream*)std::operator<<

は、それがOKコンパイルします。コンパイラが最初にメインを検索し、1つの演算子< <を見つけたので(Fooのため)、検索が停止し、誤った演算子が見つかったと文句を言いますか?繰り返しますが、引数がVecMat :: MatrixDなので、最初にVecMatのように見えるでしょうか?

私は何が起こっているのかと、可能な限りきれいに解決する方法をお勧めします。

ありがとうございます。
ミハル

PS:私も他の場所で、そこに質問を投稿、それは(http://www.cplusplus.com/forum/general/47766/#msg259246)VecMat ::演算子< <を使用してを追加することが示唆されました。行内メイン名前空間。これはそれを解決しますが、なぜ私はこれらの行が必要なのか、そしてこれが最高の/推奨される解決策であるかどうかを知りたいです。

答えて

1

typedefは新しいタイプを導入していません。したがって、VecMat::MatrixDは新しいタイプではなく、boost::numeric::ublas::matrix<double>のエイリアスです。したがって、ADLで使用される関連する名前空間はboost::numeric::ublas::matrix<double>です。

関連する問題