Implicitly convert from std::string to eastl::string - c++

I was using string class from stl std::string now I want to replace everything with eastl. So the easy question:
eastl::string obj = std::string("test");
error: conversion from ‘the::string {aka std::basic_string}’ to
non-scalar type ‘eastl::string {aka eastl::basic_string}’
requested
Is it possible to automate conversion between this types?

eastl::string obj1 = "test"; // works out of the box
eastl::string obj2 = std_string.c_str(); // equivalent to above
eastl::string obj3(&std_string[0], // another option
&std_string[0]+std_string.size());

No, not if eastl::string does not define a copy constructor/assignment operator for std::string.
The simplest way to go from a std::string to an eastl::string would be to use the .c_str() method to get a pointer to the std::string's internal char array
std::string ss("hello");
eastl::string es = ss.c_str();
You can add your own if you want to modify the library. Although that is probably a bad idea
simple example:
class MyString {
private:
char *str;
public:
MyString(const std::string &s) {
str = new char[s.length() + 1]; /* allocate */
strcpy(this->str, s.c_str()); /* copy */
}
~MyString() {
delete [] str;
}
};
Then you can create a new MyString with:
MyString ms = std::string("hello");

These classes are not compatible. eastl::string has no constructor with std::string argument. So you should use something like this:
srd::string stlstr = "test";
eastl::string eastlstr= strlstr.c_str();

Related

Overloading operator= or operator[] using const char* and/or string

I've been scouring google and stackoverflow for so-far no clear answer to this, so I'm asking directly...
I made a bitmap font class and I'd like to use an assignment operator: operator=(const char*) to assign a string literal to the text of the class.
Note: I'd also like to assign using string, string* and char*...
For example:
class BitmapText{
private:
std::string _text;
public:
void operator=(const char* _t){
_text = _t;
}
/*I've also tried another iteration of this operator using
BitmapText& operator=(const char* _t){
_text = _t;
return *this;
}
*/
BitmapText(){}
~BitmapText(){}
};
BitmapText* t1 = new BitmapText();
t1 = "Hello World"
Assigning the char string to the BitmapText object yields something like the following:
Assigning to 'BitmapText*' from 'const char[12]' incompatible type.
I'm sure there's a very good reason for this. But It can be done with the string class. I looked into the string class and it is typedef'd from:
typedef basic_string<char, char_traits<char>, allocator<char> > string;
Is this why I can assign a char array to the string class? Because it somehow seems to inherit characteristics of char? Can I overload the way I'm trying without such a complicated implementation?
My second question is (I think) along the same lines:
I want to use the operator[](const char* _name) to return a child object who's name matches the _name value.
Every operator overloading example I look at uses right-hand operands of the same class type as the one being overloaded. I have read however, you can use different data types, and we can clearly use a char* to assign a value to a std::string object...
What am I missing?
Any and all help is so greatly appreciated.
Define the operator the following way
BitmapText & operator =( const std::string &t )
{
_text = t;
return *this;
}
It can be used for objects of type std::string and for objects of type char * because there is implicit conversion from const char * to std::string due to a conversion constructor of class std::string.
As for this code snippet
BitmapText* t1 = new BitmapText();
t1 = "Hello World"
^^^ ^^
then it has to be rewritten the following way
BitmapText* t1 = new BitmapText();
*t1 = "Hello World";
This statement
t1 = "Hello World";
is wrong because you are trying to assign a pointer of type const char * to a pointer of type BitmapText *.
You're trying to assign to t1, which is not a BitmapText but a pointer to a BitmapText;
If you do *t1 = "Hello World"; it should work.
You are trying to assign to a pointer, the address of a string literal.
Instead try:
BitmapText* t1 = new BitmapText();
(*t1)= "Hello World";

Copy char num[50] to std::string

How to copy contents of char array to std::string (not conversion)
Ex :
void CApp::ChangeState(GameState* state)
{
std::string strImagePath;
// cleanup the current state
if ( !states.empty() ) {
states.back()->Clean();
states.pop_back();
//states.back()->getImagePath( psImagepath );
}
// store and init the new state
states.push_back(state);
states.back()->Init();
//psImagepath = (char*)malloc(sizeof(char)*50);
states.back()->getImagePath( psImagepath );
printf("MenuState Init path %s\n",psImagepath);
}
i want to copy my contents into strImagePath (consider strImage path is declared in class definition)
Just use the string's constructor that takes a char array:
char arr[50];
//Fill your array, do stuff, etc, etc
<...>
std::string str(arr);
Note that the char array that you are passing to the constructor should be null-terminated.
You can use strImagePath.append(charArray) to append the char[], or strImagePath.assign(charArray) to replace the previous content of strImagePath by the char[] content.
Either use the constructor (std::string(const char* str)) or copy assignment operator (std::string& operator=(const char* str)).

newbie c++; adding char* arrays?

Currently in the process of learning c++ and maybe it's because I am really frustrated right now but I really can't seem to wrap my simple little head around this:
There's a class constructor:
Class (const char* file);
I use it like this in my main class:
char* chararr = new char[2048];
//stuff with charrarr
// std::cout << chararr would be: "C:\stuff\paths\etc\"
Class c( strcat(chararr , "filename.file"));
//I want it to be: "C:\stuff\paths\etc\filename.file
Class c2( strcat(chararr , "filename2.file2"));
////I want this to be: "C:\stuff\paths\etc\filename2.file2" but it is instead
// "C:\stuff\paths\etc\filename.filefilename2.file"
The problem is that strcat modifies the chararr so the second time I do this, with Class c2, it gets all messed up... I'm guessing it's a very very basic thing to do and it gets me even more frustrated knowing I'm missing something really obvious...
Error in you code first time you should call strcpy(), whereas you are concatenates with garbage.
Class c( strcpy(chararr , "filename.file"));
else it concatenate with garbage, undefined behavior.
Edit:
// std::cout << chararr would be: "C:\stuff\paths\etc\"
size_t len = strlen(chararr); // <--- notice
Class c( strcat(chararr , "filename.file"));
// path\path2\filename.file
// ^ replace `f` with '\0'
chararr[len] = '\0'; // <--- notice
Class c2( strcat(chararr , "filename2.file2"));
Why are you using strcat when you don't need (as it seems) to concatenate strings? You could simply do:
class Class {
public:
Class(const char* file) {}
// ...
};
int main() {
Class c("filename.file");
Class c2("filename2.file2");
}
or, if you really need to concatenate strings use std::string instead of const char*.
std::string is easier to manipulate, grows in size automatically and deletes itself automatically. The only gotcha in this case, is that the class must make its own copy of the text you pass as the pointer, because when the string changes data or goes out of scope, the pointer is no longer valid.
std::string mystr = "filename.file";
MyClass c(mystr.c_str());
mystr = "filename2"; // reset string
mystr += ".file2" // concatenate
MyClass c2(mystr.c_str());
If you wrote the class, change it to use std::string as well.
class MyClass
{
public:
MyClass(const std::string& str_in)
: str(str_in) // initialization list
{
}
std::string str;
};
std::string mystr = "filename.file";
MyClass c(mystr);
mystr = "filename2"; // reset string
mystr += ".file2" // concatenate
MyClass c2(mystr);
You have to reinitialize chararr if you want to use it this way:
char* chararr = new char[2048];
strcpy(chararr,"path\\path2\\");
Class c( strcat(chararr , "filename.file"));
strcpy(chararr,"path\\path2\\");
Class c2( strcat(chararr , "filename2.file2"));
For that you're using c++ I'd recommend using std::string anyway.

Create String object from std::string by overloading = operator

I've tried several options but my compiler does not pick up the operator overloading or something else is wrong. I'm using XCode 4.5.2 with default Apple LLVM compiler 4.1.
The error I get is this: Assigning to 'cocos2d::CCString *' from incompatible type 'const char [5]'
on these lines:
CCString *s_piece__locks = "TEST";
cocos2d::CCString *s_piece__locks2 = "TEST";
My .h code:
CCString& operator= (const std::string& str);
// CCString& operator= (const char* str); // this doesn't work either
const CCString& operator = (const char *);
My .cpp code (even though this is irelevant):
CCString& CCString::operator= (const std::string& str)
{
m_sString = CCString::create(str)->m_sString;
return *this;
}
const CCString& CCString :: operator = (const char* str)
{
m_sString = CCString::create(str)->m_sString;
return *this;
}
Your help is very appreciated, thanks!
The error message Assigning to 'cocos2d::CCString *' from incompatible type 'const char [5]' suggests that you are assigning a char array to a pointer to cocos2d::CCString.
This should work:
char bar[] = "ABCD";
cocos2d::CCString foo;
foo = bar;
CCString *s_piece__locks = "TEST";
cocos2d::CCString *s_piece__locks2 = "TEST";
What the heck is this supposed to do? Declaring a pointer does not generate any object except the pointer itself. So basically, for this to "work", there would need to be another CCString object around already, that happens to represent the string "TEST". But even if that's given, how is C++ supposed to know which one to point to? It would need to look "TEST" up in some kind of e.g. hash map.
None of this makes any sense. Change your code to either
Direct use of object on stack:
cocos2d::CCString s_piece;
s_piece = "TEST";
Assigning new content to an object that resides somewhere else. You'd normally use a reference for this, e.g.
void assign_test_to(cocos2d::CCString& target) {
target = "TEST";
}
it's also possible with a pointer
void assign_test_to_ptr(cocos2d::CCString* target) {
*target = "TEST";
}
but don't do that unless you have a specific reason to.
In principle, there's another possibility:
cocos2d::CCString* s_piece_locks = new CCString;
*s_piece_locks = "TEST";
but you want to avoid this, as it can very easily lead to memory leaks. What would be ok is
std::unique_ptr<cocos2d::CCString> s_piece_locks = new CCString;
*s_piece_locks = "TEST";

issue with pointers and constructors

The following code doesn't work:
class String{
public:
char* str;
int* counter;
String(){
str = NULL;
counter = new int;
*counter = 1;
};
String(const char* str1){
String();
str = new char[strlen(str1)+1];
strcpy(str, str1);
};
};
I've changed the call to the empty constructor and replaced it with its internals, and now the following code works:
class String{
public:
char* str;
int* counter;
String(){
str = NULL;
counter = new int;
*counter = 1;
};
String(const char* str1){
//String();
str = new char[strlen(str1)+1];
strcpy(str, str1);
counter = new int;
*counter = 1;
};
Can you please suggest why?
Thanks, Li.
"Doesn't work" is not a good description of the problem. But you apparently tried to invoke a constructor from another one. That's called constructor delegation and is not (yet) supported by C++.
BTW, a class like this should get a user-defined copy constructor, assignment operator and destructor.
It seems to me you are trying to invoke a constructor from another constructor of the same class, like you would in C# for example. Unfortunately you cannot do this in C++ (at least no easy way I know of). You need to either have a private method or duplicate the code.
In the current C++, constructors cannot call each other. That's called "chaining constructors", or "delegating constructors" and is supported by the new C++0x standard but with a different syntax than the one you are using.
Off-topic, why do you use a pointer to int for the counter?
Calling String(); actually creates a temporary object and then throws it away again. It won't call the other constructor.
The call 'String();' creates an unnamed temporary object of type String that is destroyed immediately. The second code snippet is fine.
However you should really relook at the members of your class. Use std::string instead of raw char pointer. Also int *counter does not look very intuitive
You are allowed to do something like this:
class String{
public:
char* str;
int* counter;
private:
void initialize() {
str = NULL;
counter = new int;
*counter = 1;
}
public:
String(){
initialize();
};
String(const char* str1){
initialize();
str = new char[strlen(str1)+1];
strcpy(str, str1);
};
};
why is the counter a pointer ?
What does not work ? compilation error ?
Probably calling the constructor inside another is not well supported on your compiler ?
what platform ?