我遇到了重载运算符<<的问题与命名空间相结合。我已经阅读了相关的帖子,但仍然不明白我的情况发生了什么..
以下代码编译正常:
file 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
file test_oper.cpp:
#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;
}
请注意,需要使用VecMat :: operator&lt;&lt ;; 行 - 如果没有它,我会在 test1()的最后一行收到错误(使用gcc 4.5):
test_oper.cpp ||在函数'void test1()'中:|
中
test_oper.cpp | 22 |错误:不匹配'operator&lt;&lt;'在'((std :: basic_ostream *)std :: operator&lt;&lt;
编译器是否应该使用ADL找到运算符self,因为参数的类型为 VecMat :: MatrixD ?
然而,当我添加一个具有自己的运算符&lt;&lt;的新类时,我的主要问题就开始了。到 Main 名称空间:
file 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的最后一行( )
test_oper.cpp ||在函数'void Main :: test2()'中:| test_oper.cpp | 29 |错误:'operator&lt;&lt;'不匹配在'((std :: basic_ostream *)std :: operator&lt;&lt;
中
如果我将 Foo 放入另一个命名空间( VecMat 或新的命名空间),它就会编译好。这是否意味着编译器首先进入 Main ,找到一个运算符&lt;&lt;那里(对于Foo),因此停止搜索并抱怨它找到了错误的操作符?同样,我会认为它首先会查看 VecMat ,因为参数类型为 VecMat :: MatrixD ?
我很欣赏对正在发生的事情的解释以及如何以最清洁的方式解决问题的建议。
非常感谢。
米甲
PS :我也在其他地方发布了这个问题,并建议(http://www.cplusplus.com/forum/general/47766/#msg259246)使用VecMat :: operator&lt;&lt ;; 行添加也位于 Main 名称空间内。这解决了它 - 但我仍然想知道为什么我需要这些线以及这是否是最佳/推荐的解决方案。
答案 0 :(得分:1)
typedef不会引入新类型。因此VecMat::MatrixD
不是新类型,它是boost::numeric::ublas::matrix<double>
的别名,因此ADL中使用的关联命名空间是boost::numeric::ublas::matrix<double>
的命名空间。