Why initialization of const char array member incompatible in constructor initializer? - c++

I have a Test class with overloaded constructor. Initializing const char array member by string literals work fine. But, initialization by const char * gives error -
error: incompatible types in assignment of ‘const char*’ to ‘const
char [25]’
class Test
{
const char d_arr[25];
public:
Test() : d_arr("Test Class") {}
Test(const char * arr) : d_arr(arr) {}
};
How to resolve this?

You are assigning a pointer to an array, which is not allowed.
i.e. You cannot do following:
const char *arr = "ABC";
const char d_arr[25] = arr;
What you need to do is copy the chars manually i.e. something like:
Test(const char * arr) {
size_t index = 0;
if (arr) {
while (arr[index] && index < 24) {
d_arr[index] = arr[index];
++index;
}
}
d_arr[index] = 0;
}
That all said, as said in comments, its better to use std::string.

Related

Overloading subscript operator not working as expected

I have a String struct that I overloaded the subscript operator on. But it doesn't seem to work.
//my_string.h
struct String {
char* Text;
uint64 Length;
char& operator[](int32 index);
}
//my_string.cpp
char& String::operator[](int32 index) {
ASSERT(index >= 0);
return Text[index];
}
//main.cpp
String* test = string_create("Hello world");
char c = test[0];
Visual Studio gives me the following error:
no suitable conversion function from "String" to "char" exists
The compiler issued an error because in this statement
char c = test[0];
the expression test[0] has the type String.
In this declaration
String* test = string_create("Hello world");
you declared a pointer instead of an object of the type String.
If it is not a typo then in this case you have to write
char c = ( *test )[0];
or
char c = test->operator []( 0 );
Also it looks strange that the data member Length has the type uint64
uint64 Length;
while the index used in the operator has the type int32.

Initializing a 2D array member of a class in a constructor

I am getting a compile error setting a 2D array class member in the constuctor:
#include <queue>
using namespace std;
#define N 11
struct Elem {
Elem(uint32_t row, uint32_t col)
: row_(row), col_(col)
{ }
uint32_t row_, col_;
};
class Mycomp {
public:
Mycomp(int arr[][N])
{
arr_ = arr;
}
bool operator() (const Elem &lhs, const Elem &rhs)
{
return arr_[lhs.row_][lhs.col_] > arr_[rhs.row_][rhs.col_];
}
int arr_[][N];
};
int *mergeKArrays(int arr[][N], int k)
{
Mycomp mycomp(arr);
priority_queue<Elem, vector<Elem>, Mycomp> pq(mycomp);
for (uint32_t i = 0; i < k; ++i) {
pq.push(Elem(i, 0));
}
return (int *) arr;
}
int main() { }
I am getting the following error:
./mergek.cc: In constructor ‘Mycomp::Mycomp(int (*)[11])’:
./mergek.cc:23:22: error: incompatible types in assignment of ‘int (*)[11]’ to ‘int [0][11]’
arr_ = arr;
^
I have tried different variations, e.g. "&arr_[0] = arr;" did not work.
Thank you,
Ahmed.
Try to avoid using C style arrays and start using C++ containers like std::vectors, std::array, std::maps, etc.
In your code you tried to directly assign a array, which is not according to the rules and hence error would be lvalue must be modifiable value.
This problem can be rectified by visiting
error : expression must be a modifiable lvalue

operator[] overload to accept char * for subscript

I have following code:
class IList{
public:
virtual const Pair *get(const char *key) const = 0;
inline const Pair *operator[](const char *key) const;
};
inline const Pair *IROList::operator[](const char *key) const{
return get(key);
}
code compiles ok, but when I try to use it:
IList *list = (IList *) SomeFactory();
Pair *p;
p = list["3 city"];
I got:
test_list.cc:47:19: error: invalid types ‘IList*[const char [7]]’ for array subscript
p = list["3 city"];
^
I can understand that array subscript is int or char,
but then how std::map is doing char* / strings ?
If your list is a pointer as well you can't use [] operator in the way you did. That's because list["3 city"] is equivalent to list.operator[]("3 city"). If you provide pointer, you'd have to use list->operator[]("3 city") or - what is more readable - (*list)["3 city"]. Of course, you can also make your list a reference and use normally:
auto& listRef = *list;
p = listRef["3 city"];
It seems list is a pointer to IList object. So you should try:
p = (*list)["3 city"];

class myString new programmer

class mystring
{
public:
mystring(const char x[])
: capacity(1024)
{
for (int i = 0; i < capacity; ++i)
{
if (x[i] == '\0') break;
s[i] = x[i];
length++;
}
}
mystring()
: capacity(1024), s('\0'), length(0)
{}
//etc...
private:
const int capacity;
char s[1024];
int length;
};
I'm getting this error:
In file included from main.cpp:19:0:
mystring.h: In constructor ‘mystring::mystring()’:
mystring.h:21:44: error: incompatible types in assignment of ‘char’ to ‘char [1024]’
: capacity(1024), s('\0'), length(0)
I don't under stand what's going on. I'm a bit new to constructors. Thanks in advance!
Change s('\0') to s("\0")
WHEN you use single quotes, it's a single character. You must use double quotes to test it as a string.
The error you are getting right now is because that you are trying to put char into char[].
char[] is an array of char and char itself is just a char;
regularly, char[] is defined as char str[] = "Test";
Think about that and try to fix your code!
Hope this helps

Can't do a strcpy from 2D array to another 2D array

Both are in the operator= in the same class
here is the definition of the function.
void segment::operator=(const segment& w) {
strcpy(this->phrase, w.getPhrase()); //this line creates a problem.
error is below:
segment.cpp: In member function ‘void segment::operator=(const segment&)’:
segment.cpp:186: error: passing ‘const segment’ as ‘this’ argument of ‘const char*
segment::getPhrase()’ discards qualifiers
segment.cpp:186: error: cannot convert ‘char (*)[40]’ to ‘char*’ for argument ‘1’ to ‘char* strcpy(char*, const char*)’
const char* segment::getPhrase(){
return *phrase;
}
And above is the function getPhrase
I don't know why I can't do a strcpy for that.
I'm trying to completet the assignment.
EDIT:
This is the type of phrase
char phrase[10][40];
There are two problems. First you have to make getPhrase a const method. The second problem is that strcpy doesn't work with an extra level of indirection. You probably need something like this:
const char* segment::getPhrase(int index) const {
return phrase[index];
}
void segment::operator=(const segment& w) {
int index;
for (index = 0; index < 10; ++index) {
strcpy(this->phrase[index], w.getPhrase(index));
}
}
You should replace the 10 with constant
class segment {
//other stuff
static const int kNumPhrases = 10;
char phrase[kNumPhrases][40];
}