重载运算符<<与命名空间
overloading operator<< vs. namespaces
我有一个重载操作符问题<<与名称空间结合使用。我已经读了相关的帖子,但仍然不明白我的情况是怎么回事。
以下代码可以正常编译:
文件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:
#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<<;行的是必需的——没有它,我在的最后一行test1()(使用gcc 4.5)上得到一个错误:
test_op .cpp||In function 'void test1()':|
test_op .cpp|22|错误:在'((std::basic_ostream*)std::operator<<
由于参数类型为VecMat::MatrixD,编译器不应该使用ADL找到操作符self吗?
然而,我的主要问题开始于我添加一个带有自己的操作符<<的新类。到主命名空间:文件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_op .cpp||在函数'void Main::test2()':|test_op .cpp|29|错误:在'((std::basic_ostream*)std::operator<<
如果我把Foo放到一个不同的名称空间(VecMat或一个新的名称空间),它可以正常编译。这是否意味着编译器首先查找Main,找到一个操作符<<那里(对于Foo),因此停止搜索并抱怨它找到了错误的操作符?再一次,我本以为它会首先查看VecMat,因为参数的类型是VecMat::MatrixD?
如果你能解释一下发生了什么,并建议如何以最干净的方式解决这个问题,我将非常感激。
非常感谢。
米甲
PS:我也在其他地方发布了这个问题,有人建议(http://www.cplusplus.com/forum/general/47766/#msg259246)使用VecMat::operator<<;行也在Main命名空间中添加。这解决了它-但我仍然想知道为什么我需要这些行,这是否是最好的/推荐的解决方案。
typepedef不引入新类型。因此,VecMat::MatrixD
不是新类型,它是boost::numeric::ublas::matrix<double>
的别名,因此ADL中使用的关联命名空间是boost::numeric::ublas::matrix<double>
的命名空间。
- 命名空间中具有.h和.cpp文件的类
- 从父命名空间重载类型
- 在命名空间中定义函数还是限定函数
- C++:对不存在的命名空间使用命名空间指令
- 通过继承类使用来自不同命名空间的运算符
- 使用命名空间时出现多个定义错误
- CUDA内核和数学函数的显式命名空间
- 嵌套的匿名命名空间
- CMakeLists.txt中的命名空间表示法
- 类是C++中的命名空间吗
- 在命名空间中使用全局命名空间中的函数
- 如何使 std::sort 在 std::swap 和我的命名空间的模板化交换之间没有名称冲突?
- '使用命名空间{嵌套在另一个命名空间中的某个命名空间}"
- 是否可以将函数导入命名空间,但不能导出它?
- C++ C++类中的命名空间降级
- 如何使用 soong 命名空间来有条件地编译模块
- 使用 Clang++ 有没有办法将文件作为命名空间等包含?
- 使用 make 编译 MPI,几个命名空间错误,例如"错误:未知类型名称'使用'?
- 如何通过命名空间调用非静态方法
- 重载& lt; & lt;使用命名空间std