2011-08-01 14 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" '두 원본 파일 중 하나에서 .cpp 파일은 위의 동일한 오류와 함께 의 마지막 줄에만 컴파일되지 않습니다. test2()

나는 다른 네임 스페이스 ( VecMat하거나 새 중 하나)에 에게 푸를 넣으면

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

, 그것은 확인을 컴파일합니다. 컴파일러가 먼저 메인을 찾고, 연산자 < < (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>입니다.