繁体   English   中英

重载operator <<与命名空间

[英]overloading operator<< vs. namespaces

我有一个重载运算符<<与命名空间结合的问题。 我已阅读相关帖子,但仍然不明白我的情况发生了什么..

以下代码编译好:

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 <<; 需要行 - 没有它,我在test1()的最后一行得到一个错误(使用gcc 4.5):

test_oper.cpp ||在函数'void test1()'中:|
test_oper.cpp | 22 |错误:'((std :: basic_ostream *)std :: operator <<中的'operator <<'不匹配

编译器是否应该使用ADL找到运算符self,因为参数的类型为VecMat :: MatrixD

然而,当我向Main命名空间添加一个带有自己的operator <<的新类时,我的主要问题就出现了:

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 |错误:'((std :: basic_ostream *)std :: operator <<中'operator <<'不匹配

如果我将Foo放入不同的命名空间( VecMat或新的命名空间),它就可以编译好了。 这是否意味着编译器首先进入Main ,找到一个运算符<< there(for Foo),因此停止搜索并抱怨它找到了错误的运算符? 再次,我会认为它首先会考虑VecMat ,因为参数类型为VecMat :: MatrixD

我将非常感谢对正在发生的事情的解释以及如何以最清洁的方式解决问题的建议。

非常感谢。
米哈尔

PS :我也在其他地方发布了这个问题,并建议( http://www.cplusplus.com/forum/general/47766/#msg259246 )添加使用VecMat :: operator <<; 行也在Main命名空间内。 这解决了它 - 但我仍然想知道为什么我需要这些线以及这是否是最佳/推荐的解决方案。

typedef不会引入新类型。 所以VecMat::MatrixD不是一个新类型,它是boost::numeric::ublas::matrix<double>的别名,因此ADL中使用的关联命名空间是boost::numeric::ublas::matrix<double>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM