无法解决<<在运算符<<(...)中使用时跨命名空间

时间:2014-08-13 19:40:57

标签: c++ namespaces ostream

我为类(在命名空间中)编写了一个ostream运算符,其中包含在不同命名空间中定义了ostream运算符的对象。

尝试在<<函数中使用operator<<(...)时发生编译错误,但是当我将函数重命名为print(...)时,没有编译错误。除了函数的名称外,一切都是一样的。

我创建了一个简化示例,演示了该问题并使用Visual Studio 2012,gcc 4.1.2和clang 3.3进行了测试。代码如下。将#define USEOSTREAM 1更改为#define USEOSTREAM 0,以便在使用operator<<(...)print(...)

之间进行更改

我的理解是这个结构应该有效。我不愿责怪编译器,甚至更不愿意责怪这种语言。有没有人知道发生了什么?

CodePad与#define USEOSTREAM 1 http://codepad.org/b3cm038x
CodePad与#define USEOSTREAM 0 http://codepad.org/0c11PkxL

#define USEOSTREAM 1

#include <iostream>
#include <vector>

namespace Common {
    struct Foo {
    public:
        Foo(int val=0) : mVal(val) {}
        int mVal;
    };
}

namespace Utility {
    std::ostream& operator<<(std::ostream& out, const Common::Foo& obj) {
        out << obj.mVal;
        return out;
    }
}

using namespace Utility;
namespace UnitTest {

    class Bar {
    public:
        Bar(int val=0) : foo(val) {}
        Common::Foo foo;
    };

    #if USEOSTREAM

    std::ostream& operator<<(std::ostream& out, const Bar& bar) {
        out << bar.foo;                               //  Compile Error : no operator found of type 'const Common::Foo'
        // Utility::operator<<(out,vec[i]) << " " ;   //  No compile error for fully qualified name
        return out;
    }

    void printBar(const Bar& b) {
        std::cout << b;
    }

    #else

    std::ostream& print(std::ostream& out, const Bar& bar) {
        out << bar.foo;                                // No Compile Error
        return out;
    }

    void printBar(const Bar& b) {
        print(std::cout,b);
    }

    #endif

    void test01() {
        printBar(Bar(123));
    }
}

int main (int,char**) {
    UnitTest::test01();
    return 0;
}

1 个答案:

答案 0 :(得分:0)

(在编写原始的SO问题时,我找到了解决方案,但是我不明白为什么需要添加using语句)

似乎UnitTest::operator<<正在影响Utility::operator<<。解决方案是在操作符函数定义之前添加using语句。

    using Utility::operator<<;  // New Line
    std::ostream& operator<<(std::ostream& out, const Bar& bar) {
        out << bar.foo;
        return out;
    }    

此问题与以下SO帖子有关 overloading operator<< vs. namespaces和cplusplus.com论坛发帖http://www.cplusplus.com/forum/general/47766/#msg259246