`template<int N> std::ostream& operator << (…)` 不需要翻译。

huangapple go评论65阅读模式
英文:

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 &lt;iostream&gt;
#include &lt;array&gt;

template&lt;int N&gt;
std::ostream&amp; operator &lt;&lt; (std::ostream&amp; out, std::array&lt;int, N&gt; const&amp; arr) {
    for(auto&amp; a:arr) std::cout &lt;&lt; a &lt;&lt; &#39; &#39;;
    return out;
}

int main(int argc, char const* argv[]) {
    std::array&lt;int, 10&gt; arr {1,2,3,4,5,6,7,8,9,10};

    std::cout &lt;&lt; arr &lt;&lt; &#39;\n&#39;;

    return 0;
}

Why it cannot resolve N? The error message is

main.cpp:13:15: error: invalid operands to binary expression (&#39;std::ostream&#39; (aka &#39;basic_ostream&lt;char&gt;&#39;) and &#39;std::array&lt;int, 10&gt;&#39;)
    std::cout &lt;&lt; arr &lt;&lt; &#39;\n&#39;;

答案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&lt;std::size_t N&gt;
std::ostream&amp; operator &lt;&lt; (std::ostream&amp; out, std::array&lt;int, N&gt; const&amp; arr) {
    for(auto&amp; a:arr) std::cout &lt;&lt; a &lt;&lt; &#39; &#39;;
    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.

huangapple
  • 本文由 发表于 2023年1月9日 16:21:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/75054670.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定