我为类(在命名空间中)编写了一个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;
}
答案 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