英文:
template<int N> std::ostream& operator << (...)
问题
为什么这个应用程序无法编译?
#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;
}
为什么它无法解析 N
?错误消息是:
main.cpp:13:15: error: invalid operands to binary expression ('std::ostream' (aka 'basic_ostream<char>') and 'std::array<int, 10>')
std::cout << arr << '\n';
英文:
Why this application doesn't compile?
#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;
}
Why it cannot resolve N
? The error message is
main.cpp:13:15: error: invalid operands to binary expression ('std::ostream' (aka 'basic_ostream<char>') and 'std::array<int, 10>')
std::cout << arr << '\n';
答案1
得分: 10
因为std::array
的第二个模板参数的类型是std::size_t
,而不是int
。类型不匹配导致模板参数推导失败。
如果函数模板的非类型模板参数用于函数参数列表的模板参数(该参数也是一个模板),并且相应的模板参数被推导出来,那么推导出的模板参数的类型(如其封闭模板参数列表中指定的那样,即保留了引用)必须与非类型模板参数的类型完全匹配,除了cv限定符被去除,并且除非模板参数从数组界限中推导出来,在这种情况下,任何整数类型都是允许的,甚至
bool
,尽管它总是变为true
:
您可以将操作符模板更改为:
template<std::size_t N>
std::ostream& operator << (std::ostream& out, std::array<int, N> const& arr) {
for(auto& a:arr) std::cout << a << ' ';
return out;
}
英文:
Because the type of the 2nd template parameter of std::array
is std::size_t
, not int
. Type mismatch causes template argument duduction failing.
> If a non-type template parameter of function template is used in the template parameter list of function parameter (which is also a template), and the corresponding template argument is deduced, the type of the deduced template argument ( as specified in its enclosing template parameter list, meaning references are preserved) must match the type of the non-type template parameter exactly, except that cv-qualifiers are dropped, and except where the template argument is deduced from an array bound—in that case any integral type is allowed, even bool
though it would always become true
:
You can change the operator template to:
template<std::size_t N>
std::ostream& operator << (std::ostream& out, std::array<int, N> const& arr) {
for(auto& a:arr) std::cout << a << ' ';
return out;
}
答案2
得分: 2
我在VS 2022中使用C++的最新std和Microsoft编译器尝试了这段代码,int N
版本可以编译成功,哈哈。似乎它进行了某种转换。无论如何,它可以处理不匹配的情况。
但是,正如@songyuanyao已经提到的那样,你应该使用std::size_t
。
英文:
I tried the code in VS 2022 using C++'s latest std and the Microsoft compiler compiles the int N
version without problems haha. It seems like it does a sort of conversion. In any case, it could deal with the mismatch.
But yes, std::size_t
is what you should be using instead, as @songyuanyao already stated.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论