微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

vector<int> 的 ostream_iterator 无法编译为什么?

如何解决vector<int> 的 ostream_iterator 无法编译为什么?

请参阅以下最小可重现示例:

#include <iostream>
#include <vector>
#include <algorithm>

// Define inserter operator for std::vector<int>
std::ostream& operator << (std::ostream& os,const std::vector<int>& v) {
    std::copy(v.begin(),v.end(),std::ostream_iterator<int>(os," "));
    return os;
}
// Define inserter operator for std::vector<std::vector<int>>
std::ostream& operator << (std::ostream& os,const std::vector<std::vector<int>>& vv) {
    
    // ******* Error in this line *****
    std::copy(vv.begin(),vv.end(),std::ostream_iterator<std::vector<int>>(os,"\n"));

    // OK. The following works and will call the operator above
    for (const std::vector<int>& v : vv) os << v << '\n';
    return os;
}
int main() {
    std::vector<std::vector<int>> vvi{ {1,2},{3,4,5},{6,7,8,9 } };
    std::cout << vvi;
    return 0;
}

std::ostream_iterator<std::vector<int>> 不会编译,编译器说:

二进制“

虽然可以使用 std::vector<int> 的插入运算符。

如果我改为使用:

for (const std::vector<int>& v : vv) os << v << '\n';

调用 std::vector<int> 的插入运算符。但不是在 std::ostream_iterator 的情况下。

CppReference 对我没有帮助。

为什么不能编译?

解决方法

第一个问题是你缺少一个

#include <iterator>

您表示您已经熟悉 cppreference.com,因此您应该注意 std::ostream_iterator 被注明需要此头文件。

但是编译失败的真正原因是重载的运算符是由 std::copy 调用的,它自然位于 std 命名空间中。由于调用 << 运算符的代码位于 std 命名空间中,因此重载解析会在 std 命名空间中搜索 << 的已定义重载,并找到一大堆,适用于各种原生类型。所有这些重载决议都失败了。它们都不是针对std::vector<int>搜索全局命名空间,以找到您的自定义 << 重载,因为在 {{1} } 命名空间。游戏结束。

如果 << 命名空间中没有定义的 std 重载,那么重载解析最终会找到您的自定义重载。唉,事实并非如此。

消除编译错误的一种方法是将重载放入 << 命名空间:

std

然而,this is pedantic undefined behavior。在任何情况下,这都是编译错误的原因:首先在 std 命名空间中搜索 namespace std { // Define inserter operator for std::vector<int> std::ostream& operator << (std::ostream& os,const std::vector<int>& v) { std::copy(v.begin(),v.end(),std::ostream_iterator<int>(os," ")); return os; } } 的现有重载,因为它们是从 << 中调用的,并且现有的重载决议最先找到,因此不考虑其他命名空间中的其他潜在重载。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。