簡體   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