Home > Back-end >  template<int N> std::ostream& operator << (...)
template<int N> std::ostream& operator << (...)

Time:01-09

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';

CodePudding user response:

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;
}

CodePudding user response:

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.

  • Related