c – *** 作符重载解析在命名空间中如何工作?

c –  *** 作符重载解析在命名空间中如何工作?,第1张

概述我发现C解决 *** 作符超载的奇怪行为,我不能解释自己.指向描述它的某些资源的指针将与答案一样好. 我有2个翻译单位.在一个(称为util.cpp / h)中,我声明并定义了两个运算符(我忽略了可读性的真正实现,无论如何,problam都会发生): // util.h#ifndef GUARD_UTIL#define GUARD_UTIL#include <iostream>std::ist 我发现C解决 *** 作符超载的奇怪行为,我不能解释自己.指向描述它的某些资源的指针将与答案一样好.

我有2个翻译单位.在一个(称为util.cpp / h)中,我声明并定义了两个运算符(我忽略了可读性的真正实现,无论如何,problam都会发生):

// util.h#ifndef GUARD_UTIL#define GUARD_UTIL#include <iostream>std::istream& operator>>(std::istream& is,const char* str);std::istream& operator>>(std::istream& is,char* str);#endif

和:

//util.cpp#include "util.h"#include <iostream>std::istream& operator>>(std::istream& is,const char* str) {  return is;  }std::istream& operator>>(std::istream& is,char* str) {  return is;  }

如果在全局命名空间中运行,这些运算符是由于它们运行在std类型和内置类型上,并且应该可以在任何地方使用.它们可以从全局命名空间(例如从main())中正常工作,或明确告诉编译器它们在全局命名空间中(见代码示例).

在另一个翻译单元(称为test.cpp / h)中,我在命名空间中使用这些运算符.这样,直到我把一个类似的 *** 作符放在这个命名空间中.一旦添加了该 *** 作符,编译器(例如gcc或clang)就不能找到可行的运算符>>了.

// test.h#ifndef GUARD_TEST#define GUARD_TEST#include <iostream>namespace namespace {  class SomeClass {       public:      voID test(std::istream& is);  };  // without the following line everything compiles just fine  std::istream& operator>>(std::istream& is,SomeClass& obj) { return is; }; }#endif

和:

//test.cpp#include "test.h"#include "util.h"#include <iostream>voID namespace::SomeClass::test(std::istream& is) {  ::operator>>(is,"c"); //works  is >> "c" //fails}

为什么当没有运算符>>编译器找到正确的运算符在命名空间中,找不到有什么时候?为什么运算符影响编译器找到正确的能力,即使它有不同的签名?

解决这个问题的一个尝试就是放了

的std :: istream的&安培;运算符>>(std :: istream& is,const char * str){:: operator>>(is,str); }

进入命名空间,但比链接器抱怨以前的定义.所以附加:为什么链接器找到编译器找不到的东西?

解决方法 这是一个名字隐藏的问题.标准说(c 03,3.3.7 / 1)

A name can be hIDden by an explicit declaration of that same name in a nested declarative region or derived
class (10.2).

您的案例中的“名称”将是运算符>>命名空间构成嵌套声明区域.

解决这个问题的最简单方法是使用一个使用声明来声明命名空间本地运算符<&lt ;:

namespace your_namespece {    std::istream& operator>>(std::istream& is,SomeClass& obj) { return is; };     using ::operator>>;}

请注意,此功能不会干扰Koenig查找(至少在您的情况下,原则上可以),因此仍然会找到std ::的IO运算符.

PS:另一种工作方式是将这个问题定义为SomeClass的运算符为inline friend.这些函数在命名空间级别(“他们的”类之外)被声明,但从那里不可见.他们只能通过Koenig查找找到.

总结

以上是内存溢出为你收集整理的c – *** 作符重载解析在命名空间中如何工作?全部内容,希望文章能够帮你解决c – *** 作符重载解析在命名空间中如何工作?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1248103.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存