c++ - 类型别名和 operator<< 使用 ostream_iterator 重载导致无效操作数

标签 c++ c++11 iterator

我试图理解为什么我可以为 Edge1 使用 ostream_iterator|但不适用于 Edge在以下代码中:

#include <fstream>
#include <iostream>                  // for std::cout
#include <utility>                   // for std::pair

using VertexName = uint32_t;
using Edge = std::pair<VertexName, VertexName>;

struct Edge1 : public Edge {
    Edge1(VertexName x, VertexName y) : Edge(x,y) {};
};

std::ostream&
operator<<(std::ostream& os, const Edge& e) {
    os << "(" << e.first << ", " << e.second << ")";
    return os;
}

int main(int,char*[])
{
    auto e1 = Edge(4,5);
    auto e2 = Edge1(5,6);
    std::cout << e1 << ", " << e2 << std::endl;
    auto it = std::ostream_iterator<Edge1>(std::cout, ", ");
    //*it++ = e1;
    *it++ = e2;
}

```

虽然我可以同时打印出 e1e2使用重载 operator<<(std::stream& os, const Edge& e)函数,如果我尝试将 ostream_iterator 更改为 std::stream_iterator<Edge>(std::cout, ", "),我会从 clang-5.0 收到以下错误并取消注释 *it++ = e1行。

error: invalid operands to binary expression ('ostream_type' (aka 'basic_ostream<char, std::__1::char_traits<char> >') and 'const std::__1::pair<unsigned int, unsigned int>')
            *__out_stream_ << __value_;
            ~~~~~~~~~~~~~~ ^  ~~~~~~~~
/main.cpp:25:11: note: in instantiation of member function 'std::__1::ostream_iterator<std::__1::pair<unsigned int, unsigned int>, char, std::__1::char_traits<char> >::operator=' requested here
    *it++ = e1;

最佳答案

Edge不是类型它是 std::pair 的类型别名.

当然,ADL 没有发现 operator<< 的过载对于 Edge因为它是在错误的命名空间中定义的...并且您不允许在 std 命名空间中注入(inject)重载。

解决方法是:

#include <fstream>
#include <iostream>                  // for std::cout
#include <utility>                   // for std::pair
#include <iterator>                   // for std::ostream_iterator

using VertexName = uint32_t;

// Edge is now a type, in the global namespace...
struct Edge : std::pair<VertexName, VertexName> {
    using std::pair<VertexName, VertexName>::pair;
};

struct Edge1 : public Edge {
    Edge1(VertexName x, VertexName y) : Edge(x,y) {};
};

// ...and this operator<< is defined in the global namespace so
// ADL will now find it.
std::ostream&
operator<<(std::ostream& os, const Edge& e) {
    os << "(" << e.first << ", " << e.second << ")";
    return os;
}

int main(int,char*[])
{
    auto e1 = Edge(4,5);
    auto e2 = Edge1(5,6);
    std::cout << e1 << ", " << e2 << std::endl;
    auto it = std::ostream_iterator<Edge>(std::cout, ", ");
    *it++ = e1;
    *it++ = e2;
}

关于c++ - 类型别名和 operator<< 使用 ostream_iterator 重载导致无效操作数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46233041/

相关文章:

java - 在 Arraylist.iterator().next() 上遇到 ConcurrentModificationException,但我没有更改原始列表

c++ - 使用 ICU 将文本拆分为单词列表

c++ - 带有 unique_ptr 的前向声明?

c++ - 如何返回 `set` 方法的子类类型?

c++ - 执行时 : Issue with never ending loop

C++11 似乎不可能通过 shared_ptr 访问 protected 成员

c++ - 双端队列随机访问迭代器比较产生意外结果

Java - 从列表中显示 n 组记录?

c++ - 如何在括号下获取用户输入?

c++ - 找到两个 vector 相对于 vector 对象的两个成员的交集的有效方法