Search code examples
c++templatestemplate-argument-deductionnon-type-template-parameter

template<int N> std::ostream& operator << (...)


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

Solution

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