命名空间中的ostream operator <<隐藏其他ostream :: operator [duplicate]

问题描述 投票:2回答:1

使用gcc版本5.2.0(GCC)和--std = c ++ 14,如果取消注释名称空间MyNamespace中注释掉的运算符ostream,则以下代码不再编译。这是一个错误还是一个功能? (用g ++编译--c --std = c ++ 14 x.cxx)

#include <string>
#include <iostream>

typedef std::pair<std::string, std::string> StringPair;

std::ostream& operator<<( std::ostream&, const StringPair &pair) {
  std::cout <<pair.first<<"."<<pair.second;
}

namespace MyNamespace {
  class MyClass {};
  //std::ostream& operator<< (std::ostream&, const MyClass &);
  void xxx ();
}

void MyNamespace::xxx () {
  StringPair pair;pair.first="1";pair.second="2";
  std::cout <<pair<<std::endl;
}

我通过运算符<< uncommented获得的错误消息是:

x.cxx: In function ‘void MyNamespace::xxx()’:
x.cxx:18:13: error: no match for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream<char>}’ and ‘StringPair {aka std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >}’)
std::cout <<pair<<std::endl;
         ^
c++ g++ operator-overloading language-lawyer ostream
1个回答
2
投票

正如here所述,这是name hiding的一个例子。通过在命名空间operator<<中定义MyNamespace,可以隐藏更高名称空间(如全局)中的所有定义。

请注意,如here所述:

[...]此功能不会干扰Koenig查找[...],因此仍会找到来自std::的IO运营商。

(Qazxswpoi)

解决方案是使用details about Koenig lookup指令引用其他命名空间中的重载,如usinghere所述。 Michael Nastenko在评论中提到了这一点。

因此hereusing ::operator<<;指的是全局命名空间。

因此代码将变为:

::

#include <string> #include <iostream> typedef std::pair<std::string, std::string> StringPair; std::ostream& operator<<(std::ostream& os, const StringPair &pair) { os << pair.first << '.' << pair.second; return os; } namespace MyNamespace { class MyClass {}; using ::operator<<; std::ostream& operator<< (std::ostream&, const MyClass &); void xxx(); } void MyNamespace::xxx() { StringPair pair("1","2"); std::cout<<pair<<std::endl; } int main() { MyNamespace::xxx(); return 0; }

© www.soinside.com 2019 - 2024. All rights reserved.