【问题标题】:How do name-lookup and operator-overload work?名称查找和运算符重载如何工作?
【发布时间】:2018-06-12 07:53:36
【问题描述】:

我想将一些私有库class ns::A 输出到plog,所以我将operator << 重载添加到ns::A

以下代码无法编译。

error: no match for ‘operator<<’ (operand types are ‘std::ostringstream’ {aka ‘std::__cxx11::basic_ostringstream<char>’} and ‘const ns::A’)
     out << t;
     ~~~~^~~~

但是将命名空间other 更改为nsplogplog::detailstd 可以使编译错误消失,为什么? std::cout&lt;&lt;std::ostringstream&lt;&lt; 无论如何都可以正常工作。

#include <iostream>
#include <sstream>

namespace plog {
namespace detail {}
struct Record {
  template <typename T>
  Record& operator<<(const T& t) {
    using namespace plog::detail;

    out << t;
    return *this;
  }
  std::ostringstream out;
};
}

namespace ns {
struct A {};
}

namespace other {}

namespace other { // changing other to ns, plog, plog::detail or std will fix compiling error
inline std::ostream& operator<<(std::ostream& os, const ns::A& a) { return os; }
}

int main() {
  ns::A a;
  using namespace plog;
  using namespace plog::detail;
  using namespace ns;
  using namespace other;
  std::cout << a;
  std::ostringstream oss;
  oss << a;
  plog::Record s;
  s << a; // compiling error
}

【问题讨论】:

标签: c++ operator-overloading overloading name-lookup


【解决方案1】:

在你main:

int main() {
  ns::A a;
  using namespace plog;
  using namespace plog::detail;
  using namespace ns;
  using namespace other;
  std::cout << a;
  std::ostringstream oss;
  oss << a;
  plog::Record s;
  s << a; // compiling error
}

您的using namespace 仅适用于main 的范围,不会“传播”(到plog::Record::operator&lt;&lt; (const T&amp; t))。

然后s &lt;&lt; a; 将调用plog::Record::operator&lt;&lt; (const T&amp; t)T = ns::A

所以,在

Record& operator<<(const T& t)
{
    using namespace plog::detail;

    out << t;
    return *this;
}

out &lt;&lt; t;T = ns::A)将查看命名空间(使用 ADL):

  • 全局命名空间
  • 命名空间plog (plog::Record)
  • 命名空间plog::detail (using namespace plog::detail;)
  • 命名空间std (std::ostringstream out)
  • 命名空间ns (ns::A)

other::operator&lt;&lt;不被考虑,并且你没有有效的匹配,所以编译错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-09
    • 1970-01-01
    • 2017-06-07
    • 2012-07-06
    • 2015-05-25
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    相关资源
    最近更新 更多