Jefré N. Jefré N. - 3 months ago 33
C++ Question

Can't std::ostream output a const char array?

For the fun and experience of it, I'm modifying and exploring the source code for Blobby Volley 2 1.0 (Linux).

Well... I would be modifying the source code, but I can't even get the program to compile. (Sad, isn't it?)

Here's the code that causes the error:

std::ostream& operator<<(std::ostream& stream, const ServerInfo& val) {
return stream << val.name << " (" << val.hostname << ":" << val.port << ")";
}


Trying to compile this with g++ 5.4.0 gives the following (simplified output--the original output is ~443 lines) error message:


error: no match for ‘operator<<’ (operand types are ‘std::ostream {aka
std::basic_ostream}’ and ‘const char [32]’)

return stream << val.name << " (" << val.hostname << ":" << val.port << ")";


I simplified the code to this:

std::ostream& operator<<(std::ostream& stream, const ServerInfo& val) {
stream << "hello"; //can't get simpler than this, right?
return stream;
}


and got


error: no match for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream}’ and ‘const char [6]’)

stream << "hello";


The code that calls it looks like this:

std::cout << "duplicate server entry\n";
std::cout << info << "\n"; //it's called here





The thing I find most surprising is that we all know that
std::cout
and its ilk can handle
char
arrays.

For instance,

#include <iostream>
#include <string>

int main () {
const char a[6] = "hello";
std::cout << a << std::endl; //No problem here!
return 0;
}


works without a hitch.




Oh, one more thing.

If I include
<string>
, this works:

std::ostream& operator<<(std::ostream& stream, const ServerInfo& val) {
stream << std::string("hello");
return stream;
}





Does anyone know what I'm missing?




PS: Here's a pastebin of the errors.

PPS: Here's the headers that were requested:

/* header include */
#include "NetworkMessage.h"

/* includes */
#include <cstring>

#include "UserConfig.h"
#include "SpeedController.h"


PPS: If you are wondering why I didn't get an error about
std::ostream
not being defined, check the 3rd paragraph of Sam's answer.

Answer

The fact that #include <iostream> was likely missing was deduced using the Sherlock Holmes approach to debugging: "when you have eliminated the impossible, whatever remains, however improbable, must be the truth".

Clearly. std::ostream should've have had no problems accepting a const char * overload.

Therefore, an overload resolution complaint must mean that <iostream> wasn't included. Most C++ library classes are forward-declared all over the place. Including some random header file is likely to get you a forward declaration of std::ostream, as a free bonus. So the compiler will not complain about this class not being defined.

But unless <iostream> is included, the compiler will not know about all the overloads that are defined there. That's it.