c++ - 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>>
不会编译,编译器说:
二进制“<<”:未找到采用“const _Ty”类型的右侧操作数的运算符(或没有可接受的转换)
尽管可以使用插入器运算符std::vector<int>
。
如果我改为使用:
for (const std::vector<int>& v : vv) os << v << '\n';
std::vector<int>
将调用插入运算符 for 。但在std::ostream_iterator
.
CppReference 对我没有帮助。
为什么这不编译?
解决方案
第一个问题是你缺少一个
#include <iterator>
您表明您已经熟悉 cppreference.com,因此您应该注意std::ostream_iterator
需要此头文件的说明。
但是编译失败的真正原因是调用了重载的运算符,std::copy
它自然是在std
命名空间中。由于调用<<
运算符的代码位于std
命名空间中,因此重载解析会在std
命名空间中搜索已定义的 重载<<
,并为各种本机类型找到一大堆重载。所有这些重载决议都失败了。它们都不是用于std::vector<int>
. 不搜索全局命名空间来查找您的自定义<<
重载,因为在命名空间中至少<<
找到一个重载std
。游戏结束。
如果命名空间中没有定义<<
的重载std
,那么重载解析最终会找到您的自定义重载。唉,事实并非如此。
消除编译错误的一种方法是将重载放入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;
}
}
然而,这是迂腐的未定义行为。无论如何,这就是编译错误的原因:首先<<
在命名空间中搜索现有的重载std
,因为它们是从内部调用的std::copy
,并且首先找到现有的重载解决方案,因此不考虑其他命名空间中的其他潜在重载.
推荐阅读
- python - 随机森林回归 MAE
- angular - 我有角度的类模型有变量和函数,所以当我调用函数时它给了我错误
- ruby-on-rails - Heroku 服务器上的数据库中似乎不存在类别和子类别
- python - 有没有办法从 PyPI 访问搜索结果而无需抓取?
- android - 从 webview 加载的在线页面超链接到应用程序的本地 html 页面
- python - 如何使用pyglet创建免费游戏碰撞?
- html - div 在所有桌面上的位置不一致
- android - 如何使用 Coroutines 在 Kotlin 中正确初始化 Recyclerview?
- django - Django Rest Framework - 删除问题 - 找不到 CSRF
- api - 有没有办法使用 Google Sheets API v4 获取可用的货币格式?