类型别名和运算符<<使用ostream_iterator重载会导致无效的操作数

时间:2017-09-15 06:26:12

标签: c++ c++11 iterator

我试图了解为什么我可以在None中使用ostream_iterator,但在以下代码中不能使用Edge1

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,但如果我尝试将ostream_iterator更改为{{1},我会从clang-5.0中收到以下错误并取消注释operator<<(std::stream& os, const Edge& e)行。

std::stream_iterator<Edge>(std::cout, ", ")

1 个答案:

答案 0 :(得分:3)

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

当然,ADL没有为operator<<找到Edge的重载,因为它是在错误的命名空间中定义的......并且不允许在std命名空间中注入重载。 / p>

解决方法是:

#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;
}