为什么重载std::array输出运算符的C++代码无法编译?
为什么重载std::ostream<<输出std::array<int,N>时无法解析模板参数?
问题代码
#include <iostream> #include <array> template<int N> std::ostream& operator << (std::ostream& out, std::array<int, N> const& arr) { for(auto& a:arr) std::cout << a << ' '; return out; } int main(int argc, char const* argv[]) { std::array<int, 10> arr {1,2,3,4,5,6,7,8,9,10}; std::cout << arr << '\n'; return 0; }
编译错误
main.cpp:13:15: error: invalid operands to binary expression ('std::ostream' (aka 'basic_ostream
') and 'std::array<int, 10>')
std::cout << arr << '\n';
原因解析
核心问题有两点:
- 模板参数类型不匹配:
std::array的第二个模板参数是std::size_t类型,而你定义的重载函数模板参数是int N。编译器推导模板参数时,无法将std::size_t类型的10隐式转换为int,导致模板匹配失败。 - ADL查找规则:
std::array属于std命名空间,编译器处理std::cout << arr时,会在std命名空间和全局命名空间查找合适的operator<<,但由于参数类型不匹配,找不到你定义的重载版本。
修正方案
方案一:修正模板参数类型(推荐)
将模板参数int N改为std::size_t N,同时修复循环中硬编码std::cout的逻辑错误(应该使用传入的out输出流):
#include <iostream> #include <array> template<std::size_t N> std::ostream& operator << (std::ostream& out, std::array<int, N> const& arr) { for(auto const& a : arr) out << a << ' '; return out; } int main(int argc, char const* argv[]) { std::array<int, 10> arr {1,2,3,4,5,6,7,8,9,10}; std::cout << arr << '\n'; return 0; }
方案二:将重载函数放入std命名空间(不推荐)
虽然C++标准不建议向std命名空间添加自定义内容,但可以将operator<<定义在std中让ADL找到:
#include <iostream> #include <array> namespace std { template<std::size_t N> ostream& operator << (ostream& out, array<int, N> const& arr) { for(auto const& a : arr) out << a << ' '; return out; } } int main(int argc, char const* argv[]) { std::array<int, 10> arr {1,2,3,4,5,6,7,8,9,10}; std::cout << arr << '\n'; return 0; }
内容的提问来源于stack exchange,提问作者asmbaty
相关产品推荐
相关产品推荐

