本文介绍了重载运算符<<与命名空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对重载运算符有疑问<<与名称空间结合.我已经阅读了相关文章,但仍然不了解我的情况.

I have a problem with overloading operator<< combined with namespaces. I have read the related posts, but still do not understand what is going on in my case..

以下代码可以编译:

文件test_matrix.hpp:

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

文件test_oper.cpp:

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):

Note that the using VecMat::operator<<; line is needed - without it, I get an error on the last line of test1() (using gcc 4.5):

由于参数的类型为 VecMat :: MatrixD

但是,我的主要问题开始于当我添加一个具有自己的运算符的新类时.到 Main 名称空间:

My main problem, however, starts when I add a new class with its own operator<< to the Main namespace:

文件test_other.hpp:

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"",则仅在 test2( )

If I then '#include "test_other.hpp"' from either of the two original files, the .cpp file won't compile, with the same error as above, only in the last line of test2()

如果将 Foo 放入另一个命名空间( VecMat 或新的命名空间)中,它将编译确定.这是否意味着编译器首先查看 Main ,找到一个运算符<<在那里(对于Foo),因此停止搜索并抱怨它找到了错误的运算符?再次,我以为它将首先考虑 VecMat ,因为该参数的类型为 VecMat :: MatrixD ?

If I put Foo into a different namespace (either VecMat or a new one), it compiles OK. Does it mean that the compiler looks first into Main, finds one operator<< there (for Foo), and therefore stop searching and complains that it has found the wrong operator? Again, I would have thought that it would look into VecMat first, since the argument is of type VecMat::MatrixD?

对于所发生的事情的解释以及如何以最简洁的方式解决问题的建议,我将不胜感激.

I would appreciate both an explanation of what is going on and a recommendation how to resolve it in a cleanest possible way.

非常感谢.
米哈尔

Thanks a lot.
Michal

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

PS: I posted the question also elsewhere and there it was suggested (http://www.cplusplus.com/forum/general/47766/#msg259246) to add the using VecMat::operator<<; line also inside the Main namespace. This solves it - but I would still like to know why do I need those lines and whether this is the best/recommended solution.

推荐答案

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

typedef doesn't introduce a new type. So VecMat::MatrixD is not a new type, it's an alias to boost::numeric::ublas::matrix<double>, therefore the associated namespaces used in ADL are those of boost::numeric::ublas::matrix<double>.

这篇关于重载运算符&lt;&lt;与命名空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-25 00:48