C++ Error: Incompatible types in assignment of ‘char*’ to ‘char [2]
When a function wants an array as argument, it gets a pointer to the first element of an array instead. This pointer cannot be used to initialize an array, because it's a pointer, not an array.
You can write functions that accept references to arrays as arguments:
void i_dont_accept_pointers(const char (array&)[2]) {}
The problem here is, that this array reference cannot be used to initialize another array.
class Foo {
char vars[2];
Foo(const char (args&)[2])
: vars(args) // This will not work
{}
};
C++ 11 introduced std::array
to eliminiate this and other problems of arrays. In older versions, you will have to iterate through the array elements and copy them individually or use std::copy
.
Raw arrays in C++ are kind of annoying and fraught with peril. This is why unless you have a very good reason to you should use std::vector
or std::array
.
First off, as others have said, char[2]
is not the same as char*
, or at least not usually. char[2]
is a size 2 array of char
and char*
is a pointer to a char
. They often get confused because arrays will decay to a pointer to the first element whenever they need to. So this works:
char foo[2];
char* bar = foo;
But the reverse does not:
const char* bar = "hello";
const char foo[6] = bar; // ERROR
Adding to the confusion, when declaring function parameters, char[]
is equivalent to char*
. So in your constructor the parameter char short_name[2]
is really char* short_name
.
Another quirk of arrays is that they cannot be copied like other types (this is one explanation for why arrays in function parameters are treated as pointers). So for example I can not do something like this:
char foo[2] = {'a', 'b'};
char bar[2] = foo;
Instead I have to iterate over the elements of foo
and copy them into bar
, or use some function which does that for me such as std::copy
:
char foo[2] = {'a', 'b'};
char bar[2];
// std::begin and std::end are only available in C++11
std::copy(std::begin(foo), std::end(foo), std::begin(bar));
So in your constructor you have to manually copy the elements of short_name
into short_name_
:
Territory::Territory(std::string name, char* short_name, Player* owner,
char units) : name_(name), owner_(owner), units_(units)
{
// Note that std::begin and std::end can *not* be used on pointers.
std::copy(short_name, short_name + 2, std::begin(short_name));
}
As you can see this is all very annoying, so unless you have a very good reason you just should use std::vector
instead of raw arrays (or in this case probably std::string
).