I cannot compile with g++ a simple code that works perfectly in MSVC.
The code involves operator overload for ostream << array<T,D>, and g++ cannot find it, even though it's right here. Wherein the similar overload for ostream << vector doesn't cause any problem for g++.
A demo:
#include <iostream>
#include <vector>
#include <array>
template <class T> inline std::ostream& operator << (std::ostream& os, std::vector<T> &v) {
const int D = v.size();
os << "[";
if (D > 0) os << v[0];
for (int i = 1; i < D; i++) os << "," << v[i];
os << "]";
return os;
};
template <class T, int D> std::ostream& operator << (std::ostream& os, std::array<T, D> &a) {
os << "[";
if (D > 0) os << a[0];
for (int i = 1; i < D; i++) os << "," << a[i];
os << "]";
return os;
};
int main() {
std::vector<double> v = {1,2,3,4};
std::cout << v << std::endl;
//std::array<double, 2> a = { 1,2 }; <-- this lines won't compile in g++
//std::cout << a << std::endl;
return 0;
}
The commented lines cause g++ to spit a huge list of complains, starting with
test.cpp:33:12: error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'std::array<double, 2>')
33 | std::cout << a << std::endl;
| ~~~~~~~~~ ^~ ~
| | |
| | std::array<double, 2>
| std::ostream {aka std::basic_ostream<char>}
and ending with
ostream:691:5: error: no type named 'type' in 'struct std::enable_if<false, std::basic_ostream<char>&>'
The g++ version is
g++.exe (Rev2, Built by MSYS2 project) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
The same story is with other operators, but I left only the essential part.
Why is that and how to solve?
I need the code compiled by g++, because in has __float128. And I need the templates, because it's a part of generalized algorithm.
Please note that I'm new to C++.
I searched for similar cases but didn't any, at least not something helpful.
The non-type template argument of std::array
is of type size_t
not int
.
I am not sure which compiler is right here, but gcc accepts the code if you fix that:
template <class T, size_t D> std::ostream& operator << (std::ostream& os, std::array<T, D> &a) {
os << "[";
if (D > 0) os << a[0];
for (int i = 1; i < D; i++) os << "," << a[i];
os << "]";
return os;
};
PS: Note that overloading <<
for types you do not own comes with certain caveats. A function template template <typename T,size_t D> void print(const std::array<T,D>&)
can do the printing as well.