I'm trying to run the following code:
#include <iostream>
#include <array>
struct newperson {
std::array<char, 20> name{};
int age;
};
int main() {
newperson nicolas = {
"Nicolas",
21
};
newperson martin = {
"Martin",
45
};
std::cout << nicolas.age << std::endl;
std::cout << martin.name << std::endl;
return 0;
}
, which is a struct example
I get the following errors:
bast.cpp: In function 'int main()':
bast.cpp:21:19: error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'std::array<char, 20>')
21 | std::cout << martin.name << std::endl;
| ~~~~~~~~~ ^~ ~~~~~~~~~~~
| | |
| | std::array<char, 20>
| std::ostream {aka std::basic_ostream<char>}
C:/msys64/mingw64/include/c /12.2.0/ostream:754:5: error: no type named 'type' in 'struct std::enable_if<false, void>'
Is some different syntax required? I did take an existing example and change the C-style array to a standard one, after all.
And if I comment out the Martin lines, I get the following:
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\msys64\tmp\ccClI6JG.o:bast.cpp:(.text 0x42): undefined reference to `std::ostream::operator<<(int)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\msys64\tmp\ccClI6JG.o:bast.cpp:(.text 0x54): undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\msys64\tmp\ccClI6JG.o:bast.cpp:(.text 0x76): undefined reference to `std::ios_base::Init::~Init()'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\msys64\tmp\ccClI6JG.o:bast.cpp:(.text 0xa9): undefined reference to `std::ios_base::Init::Init()'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\msys64\tmp\ccClI6JG.o:bast.cpp:(.rdata$.refptr._ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_[.refptr._ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_] 0x0): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\msys64\tmp\ccClI6JG.o:bast.cpp:(.rdata$.refptr._ZSt4cout[.refptr._ZSt4cout] 0x0): undefined reference to `std::cout'
collect2.exe: error: ld returned 1 exit status
That seems to be a problem with mingw/msys2, though, because it works with Godbolt and tio.run
CodePudding user response:
There is no overloaded <<
(stream output) operator for the std::array
container, whatever the element type. However, that array container does have a .data()
member, which yields a pointer to the first element; in your case, that will be a char*
and the relevant specialisation for outputting a char*
(assuming that points to a properly null-terminated string/array) will do what you want:
std::cout << martin.name.data() << std::endl;
But, as pointed out in the comments, you would be far better off using a std::string
, here, unless there is a specific reason why you need a fixed-length array in your structures.
(If you adapted this from code that used a "C-style" array for the .name
member – i.e. char name[20];
– then the <<
would work because that array name will automatically 'decay' into a pointer to its first element; this doesn't happen for std::array
.)
Alternatively, although there is no <<
ostream
overload for the array<char, N>
container provided by the Standard Library, you could provide your own. This can be implemented as a function template (so that different array sizes could be used), like this:
template <size_t N>
std::ostream& operator << (std::ostream& os, std::array<char, N> ArrChar)
{
return os << ArrChar.data();
}