在下面的代码中,有人可以解释为什么如果启用了用“ifdef TEST”定界的代码,为什么我定义的用于打印枚举的operator <
如果我使用g++ filename.cpp构建,则输出为:
Print for Container: mycolor is red
如果我使用g++ -DTEST filename.cpp进行构建,则输出为:
Print for Container: mycolor is 0
代码如下:
#包括
namespace mynamespace
{
enum color {red, blue};
}
namespace mynamespace
{
class Container
{
public:
mynamespace::color mycolor1;
explicit Container() : mycolor1(mynamespace::red) {};
std::ostream &Print(std::ostream& os) const;
};
class Container2
{
};
}
std::ostream & operator<<(std::ostream &os, const mynamespace::color &_color);
namespace mynamespace
{
#ifdef TEST
// If this is defined, the printing of the enum in Container does not use the operator<< function to output the enum as a string
std::ostream& operator<<(std::ostream &os, const Container2 &i);
#endif
}
int main()
{
// Create a Container. Default color is red
mynamespace::Container *container = new mynamespace::Container;
container->Print(std::cout);
}
std::ostream & mynamespace::Container::Print(std::ostream &os) const
{
os << "Print for Container: mycolor is " << mycolor1 << std::endl;
return os;
}
std::ostream& operator<<(std::ostream &os, const mynamespace::color &_color)
{
switch(_color)
{
case mynamespace::red: os << "red"; break;
case mynamespace::blue: os << "blue"; break;
default: os << "unknown"; break;
}
return os;
}
最佳答案
简化示例:
namespace mynamespace
{
enum color {red, blue};
class Container
{
public:
mynamespace::color mycolor1;
explicit Container() : mycolor1(mynamespace::red) {};
std::ostream &Print(std::ostream& os) const;
};
class Container2
{
};
std::ostream& operator<<(std::ostream &os, const Container2 &i);
}
std::ostream & operator<<(std::ostream &os, const mynamespace::color &_color);
std::ostream & mynamespace::Container::Print(std::ostream &os) const
{
os << mycolor1 << std::endl;
return os;
}
表达式
os << mycolor1
寻找一个名为operator<<
的函数。该函数将作为std::ostream
的成员函数进行搜索,并且(独立地,另外)通过不合格的查找进行搜索,从而触发ADL。通过ADL进行的不合格查找将找到
mynamespace::operator<<
。“纯”不合格查找(无ADL)将从
Print
函数体的范围开始,该范围是Container
(*)类的范围,并遍历周围的范围,直到找到名为operator<<
的函数。然后停止。在这里,它也停止在mynamespace
上:这是第一个具有该名称功能的周围范围。不搜索全局 namespace 。您可以使“纯”不合格的查找找到全局函数,例如通过说:
std::ostream & mynamespace::Container::Print(std::ostream &os) const
{
using ::operator<<;
os << mycolor1 << std::endl;
return os;
}
(*)您可以将其视为
namespace mynamespace { enum color {red, blue}; class Container2; }
std::ostream& operator<<(std::ostream &os, const mynamespace::color &_color);
namespace mynamespace
{
std::ostream & operator<<(std::ostream &os, const Container2 &i);
class Container
{
public:
mynamespace::color mycolor1;
explicit Container() : mycolor1(mynamespace::red) {};
std::ostream &Print(std::ostream& os) const
{
os << mycolor1 << std::endl;
return os;
}
};
};
在这里,可能更清楚的是,包含名为
os << mycolor1
的函数的operator<<
的第一个周围范围是mynamespace
。恕我直言,一个好的解决方案是将枚举的
operator<<
也放入mynamespace
中:namespace mynamespace
{
enum color {red, blue};
std::ostream & operator<<(std::ostream &os, const mynamespace::color &_color);
}
这样,可以通过ADL找到它。
关于c++ - 为什么不使用用于枚举的operator <<?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19793523/