c++ - 使用 STL 算法的命名空间和用户定义的运算符

标签 c++ c++11 compiler-errors operator-overloading stl-algorithm

当我试图通过 std::copy 输出元素时,我遇到了难以理解的行为.以下代码正在编译并且工作正常。

namespace Foo {
  enum class Colors { green, red, blue };

  template <typename T>
  std::ostream &operator << (std::ostream &_os, const T &_t) {
      _os << typename std::underlying_type<T>::type(_t);
      return _os;
  }
}

int main() {
  Foo::Colors colors[] = {Foo::Colors::red, Foo::Colors::red, Foo::Colors::blue};

  for( auto c: colors ) { std::cout << c <<std::endl; }

  std::copy(colors, colors + 4, std::ostream_iterator<Foo::Colors>(std::cout, " "));
}

但是,如果我转operator <<来自 Foo范围,它会出现问题 std::copy .

namespace Foo {
  enum class Colors { green, red, blue };
}

template <typename T>
std::ostream &operator << (std::ostream &_os, const T &_t) {
  _os << typename std::underlying_type<T>::type(_t);
  return _os;
}

int main() {
  Foo::Colors colors[] = {Foo::Colors::red, Foo::Colors::red, Foo::Colors::blue};

  for( auto c: colors) { std::cout << c <<std::endl; } // works fine

  // arising compiler error
  std::copy(colors, colors + 4, std::ostream_iterator<Foo::Colors>(std::cout, " ")); 

  // do not help, too
  {
    using namespace Foo;
    std::copy(colors, colors + 4, std::ostream_iterator<Colors>(std::cout, " ")); 
  }
}

此行为的原因是什么,正确的解决方法是什么?

最佳答案

您的模板接受所有内容并会导致歧义:

一个较小的测试用例:

#include <iostream>

// error: ambiguous overload for ‘operator<<’ in ‘std::cout << '\012'’
template <typename T>
std::ostream &operator << (std::ostream &_os, const T &_t) {
  _os << typename std::underlying_type<T>::type(_t);
  return _os;
}

int main() {
    std::cout << '\n';
}

由于 ADL(参数相关查找),在您的命名空间中只有一个且只有一个 (!) 运算符 << 将解决它

关于c++ - 使用 STL 算法的命名空间和用户定义的运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22372886/

相关文章:

c++ - 为什么在使用嵌套的 OpenMP pragma 时 c++11 线程变得不可连接?

C++ 如何将 emplace_back 用于用户定义的结构

c++ - 从 vmware 识别主机

c++ - C++ 中数组对象的隐式类型转换

c++ - “error: expected primary-expression before ' <= ' token”我在做什么错?

C++ 模板复制构造函数,编译器说 "passing const as this argument discards qualifiers"

android - 错误 : unaligned opcodes detected in executable segment

c++ - 容器超出范围和内存管理

c++ - 已完成线程使用的免费资源

c++ - 使用 G++ 构建时出现错误 1