gpt4 book ai didi

c++ - 为什么没有使用 operator<< for enum?

转载 作者:搜寻专家 更新时间:2023-10-31 00:37:27 24 4
gpt4 key购买 nike

在下面的代码中,有人可以解释为什么如果启用了由“ifdef TEST”分隔的代码,我定义的用于将枚举打印为字符串的 operator<< 函数没有被使用。在我看来,导致我的问题的代码应该与 Container 类中枚举的打印无关,尤其是因为问题代码引用了不同的类 (Container2)。

如果我使用 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。以及:这是第一个具有同名函数的周围作用域。全局命名空间未被搜索

您可以使“纯”非限定查找找到全局函数,例如通过说:

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<< for enum?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19793523/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com