Why can't gcc deduce templated size for array argument? (C++11)
c++, c++11, gcc, templates
Solution
Consider your declaration:
template <typename T, int N>
std::ostream & operator <<(std::ostream & os, const std::array<T, N> & arr) {
The definition for `std::array` is:
template<typename T, std::size_t N> class array {...};
You are using `int` instead of `std::size_t`, and that's why it doesn't match.
Problem
The following code gives a compiler error (gcc-4.7 run with `-std=c++11`): ``` #include <iostream> #include <array> template <typename T, int N> std::ostream & operator <<(std::ostream & os, const std::array<T, N> & arr) { int i; for (i=0; i<N-1; ++i) os << arr[i] << " "; os << arr[i]; return os; } int main() { std::array<double, 2> lower{1.0, 1.0}; std::cout << lower << std::endl; return 0; } ``` Error message: tmp6.cpp: In function ‘int main()’: tmp6.cpp:16:16: error: cannot bind ‘std::ostream {aka std::basic_ostream}’ lvalue to ‘std::basic_ostream&&’ In file included from /usr/include/c++/4.7/iostream:40:0, from tmp6.cpp:1: /usr/include/c++/4.7/ostream:600:5: error: initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits; _Tp = std::array]’ When I get rid of the template function declaration and replace `T` with `double` and `N` with `2`, it compiles just fine (edit: leaving `T` and replacing `N` with 2 works, but specifying `N=2` as the default argument for `N` doesn't work.). - Does anyone know why gcc can't automatically bind this? - What would be the syntax for calling the `<<` operator with explicitly specified template parameters? Answer to question 2: `operator<<<double, 2>(std::cout, lower);` Edit: This is also true for the following function, which is only templated in the array size: ``` template <int N> void print(const std::array<double, N> & arr) { std::cout << "print array here" << std::endl; } int main() { std::array<double, 2> lower{1.0, 1.0}; print<2>(lower); // this works print(lower); // this does NOT work return 0; } ``` Thanks a lot for your help.