Conversion of std::basic_string to std::string?

Started by
21 comments, last by Zahlman 18 years, 5 months ago
I'm calling a function that requires a std::string as its first parameter, but I'm passing it a std::basic_string:
Quote: CINIParser parser(_pcIniFileName); Int32 iStringLength = static_cast<Int32>(_strStringName.length()); for(int i = 0; i < iStringLength; i++) { std::basic_string <char>::reference strCurrentLetter = _strStringName; Int32 iStartX; Int32 iStopX; Int32 iStartY; Int32 iStopY; parser.GetIntValue(strCurrentLetter, "frame", iStartX); parser.GetIntValue(strCurrentLetter, "frame", iStopX); parser.GetIntValue(strCurrentLetter, "frame", iStartY); parser.GetIntValue(strCurrentLetter, "frame", iStopY); }
The errors I am receiving are for the last four lines of code, (beginning with parser.GetIntValue):
Quote:e:\Documents and Settings\David & Angela\Desktop\Rugby League Manager\Font.cpp(71): error C2664: 'CINIParser::GetIntValue' : cannot convert parameter 1 from 'std::allocator<_Ty>::value_type' to 'std::string' with [ _Ty=char ] e:\Documents and Settings\David & Angela\Desktop\Rugby League Manager\Font.cpp(72): error C2664: 'CINIParser::GetIntValue' : cannot convert parameter 1 from 'std::allocator<_Ty>::value_type' to 'std::string' with [ _Ty=char ] e:\Documents and Settings\David & Angela\Desktop\Rugby League Manager\Font.cpp(73): error C2664: 'CINIParser::GetIntValue' : cannot convert parameter 1 from 'std::allocator<_Ty>::value_type' to 'std::string' with [ _Ty=char ] e:\Documents and Settings\David & Angela\Desktop\Rugby League Manager\Font.cpp(74): error C2664: 'CINIParser::GetIntValue' : cannot convert parameter 1 from 'std::allocator<_Ty>::value_type' to 'std::string' with [ _Ty=char ]
1) Is there a simple method to convert the std::basic_string to a std::string? I have tried both static_cast and reinterpret_cast, but to no avail. 2) Even better, is there a std::string method for finding a particular variable within a string, such as what I am using the std::basic_string line of code for:
Quote:std::basic_string <char>::reference strCurrentLetter = _strStringName;
That way, I wouldn't need to worry about any conversion problems! :)
Advertisement
Your problem is not "I'm calling a function that requires a std::string as its first parameter, but I'm passing it a std::basic_string".

Your problem is that your function requires a std::string, but you're passing it a std::allocator<char>::value_type, which is a probably a typedef for just 'char'.

I have no idea why you are using basic_string. std::string is usually a typedef of std::basic_string<char>, so it's the -same thing-.

Where did that Int32 come from?

Why don't you just try this:

char& letter = some_string;
parser.GetIntValue( letter, "frame", iStartX );
//... etc



"finding a particular variable within a string" <-- what do you mean? There are no 'variables within a string', it's just a collection of characters. If you want to extract one character, you can use operator[] as you did, or you can iterate over the string (better), or you can use std::for_each (even better)
Quote:Original post by RDragon1I have no idea why you are using basic_string. std::string is usually a typedef of std::basic_string<char>, so it's the -same thing-.


I'm using basic_string because it works. I didn't realise it was effectively a char.

Quote:Where did that Int32 come from?


I'm not sure which one you're referring to, as there are a few. Can you be more specific?

Quote:Why don't you just try this:

char& letter = some_string;
parser.GetIntValue( letter, "frame", iStartX );
//... etc


I tried that, but that brings me back to requiring a conversion from char to std::string. Do you have any recommendations as to how to do that? static_cast and reinterpret_cast don't seem to do the trick.

Quote:"finding a particular variable within a string" <-- what do you mean? There are no 'variables within a string', it's just a collection of characters. If you want to extract one character, you can use operator[] as you did, or you can iterate over the string (better), or you can use std::for_each (even better)


Sorry, I meant characters, not variables. How would I iterate or apply std::for_each in this situation? Does that mean I'd need to implement a new function that I call each time within the loop?
Quote:Original post by Jesbass
I'm using basic_string because it works. I didn't realise it was effectively a char.

It's not. basic_string is a class template. basic_string< char > is an instantiation of that template for ansi-style strings. Because basic_string has default template parameters basic_string< char > is shorthand for basic_string< char, char_traits< char >, allocator< char > >. string on the otherhand is a direct typedef of basic_string< char, char_traits< char >, allocator< char > >. So string and basic_string< char > are exactly the same type and can even be used interchangeably. You should prefer to use string, since this is most familiar to people and shorter to type.

Quote:I tried that, but that brings me back to requiring a conversion from char to std::string. Do you have any recommendations as to how to do that? static_cast and reinterpret_cast don't seem to do the trick.

The problem is that you are trying to pass a char to a function that expects a string. You are almost certainly misusing the function. What exactly does parser.GetIntValue do?

Quote:Sorry, I meant characters, not variables. How would I iterate or apply std::for_each in this situation? Does that mean I'd need to implement a new function that I call each time within the loop?

I'm not sure if it even makes sense to iterate over the characters. Sort out the previous problem first.

Enigma
std::basic_string <char>::reference is a reference to char, not a reference to std::basic_string<char>. From there, the solution to your problem should be fairly obvious.

CM
std::basic_string <char>::reference strCurrentLetter = _strStringName[e];


As mentioned, std::basic_string<char> is the exact same thing as std::string. What you therefore have is std::string::reference, i.e. the 'reference' typedef *provided by* the std::string class. That is not a reference to a std::string (that would be spelled 'std::string&'), but instead what the type happens to be - a reference to a char, i.e. an *element* of the string. That is consistent with the illustrated indexing: "_strStringName[e]" will yield a single character of the string.

I think the problem here is logical: Iteration over the characters of the string doesn't make sense here. You are effectively asking the function to parse four numbers out of each letter - how's that going to work? What exactly is the string supposed to contain in terms of these numbers, and what do you want to do with them?

Also, please show the CINIParser::GetIntValue() function, assuming it is also your code. It appears to have a much clumsier interface than what is required.
Thanks for the interest, guys. I appreciate you all trying to help. :)

Quote:Original post by Enigma
The problem is that you are trying to pass a char to a function that expects a string. You are almost certainly misusing the function. What exactly does parser.GetIntValue do?


Yeah, I realise that is my problem, which is why I was trying to find a std::string function that performs the same task, (i.e. locating a specific character within a string).

parser.GetIntValue is part of my .ini parser - it opens a .ini file and retrieves an int value. Which int value it returns is dependent on the first two variables, which act as a key to direct the parser to the correct location within the .ini parser.

Quote:Original post by Enigma
I'm not sure if it even makes sense to iterate over the characters. Sort out the previous problem first.


That was RDragon's suggestion, not mine. ;) I'm happy to let that suggestion slide if it means I can get around this problem.

Quote:Original post by Conner McCloud
std::basic_string <char>::reference is a reference to char, not a reference to std::basic_string<char>. From there, the solution to your problem should be fairly obvious.


Hehe, not to me it isn't! :P If it were obvious, I probably would have sorted it out by now. I still find myself either wanting to convert a char into a std::string somehow, or finding a std::string function that will perform the same action.

Quote:Original post by Zahlman
I think the problem here is logical: Iteration over the characters of the string doesn't make sense here. You are effectively asking the function to parse four numbers out of each letter - how's that going to work? What exactly is the string supposed to contain in terms of these numbers, and what do you want to do with them?


Each letter is a key to a particular location within a .ini file. Each letter of the alphabet, (this is for drawing fonts from a texture), has four numbers, effectively indicating the (startx,starty) and (stopx,stopy) parameters of a rectangle. Each rectangle will hopefully then be placed onto the screen as a texture, meaning the entire string gets written onto the screen.

Quote:Original post by Zahlman
Also, please show the CINIParser::GetIntValue() function, assuming it is also your code. It appears to have a much clumsier interface than what is required.


Sure. :)

bool
CINIParser::GetIntValue(std::string _strBlock, std::string _strKey, Int32& _iValue)
{
std::string strMyKey;

strMyKey = _strBlock + "|" + _strKey;

IterStringMap iter = m_mapPairs.find(strMyKey);

if (iter != m_mapPairs.end())
{
std::string temp = ((*iter).second);
_iValue = atoi(temp.c_str());

return true;
}

return false;
}

I hope that helps. If I can convert a char to a strgin somehow, I'll be happy. And if I can get a std::string piece of code that will single out a character within a string, I'll be equally happy. Again, thanks for your help, guys. :)
1. std::string is equivalent to std::basic_string< char >, as has been pointed out. All operations on and members of the latter work with the former. Many people will get confused if you use the latter, so use the former.

2. If you really want to pass only a single character as the first argument to GetIntValue, pass it by value, not by reference. If you're actually wanting to pass a substring of the original string, use the substr() function.

3. The original code you posted has no effect. Each time through the loop, it searches four times for a key named "frame" in a block named whatever the character at i is, and writes the value if found to a temporary variable inside the loop. Is this your actual code?

EDIT:
Quote:If I can convert a char to a strgin somehow, I'll be happy. And if I can get a std::string piece of code that will single out a character within a string, I'll be equally happy.
For the first, std::string has a constructor that takes a number and a char; it also has an assignment (=) operator that takes a char. For the second, the index operator.
std::string mystring = "Hello, world!";char c = mystring[4]; // 'o'
{[JohnE, Chief Architect and Senior Programmer, Twilight Dragon Media{[+++{GCC/MinGW}+++{Code::Blocks IDE}+++{wxWidgets Cross-Platform Native UI Framework}+++
Quote:Original post by TDragon
1. std::string is equivalent to std::basic_string< char >, as has been pointed out. All operations on and members of the latter work with the former. Many people will get confused if you use the latter, so use the former.


So how do I use std::string to retrieve a single character, if that is the case?

Quote:Original post by TDragon
2. If you really want to pass only a single character as the first argument to GetIntValue, pass it by value, not by reference. If you're actually wanting to pass a substring of the original string, use the substr() function.


Yeah, only a single character. How do I pass it by value instead of by reference?

Quote:Original post by TDragon
3. The original code you posted has no effect. Each time through the loop, it searches four times for a key named "frame" in a block named whatever the character at i is, and writes the value if found to a temporary variable inside the loop. Is this your actual code?


Yes, that's my actual code. That's all I want it do for now. Once I've removed my errors I can move onto the next piece of code related to this code segment. I am of the understanding that it would be bad programming practice to simply continue on by ignoring the errors I'm receiving.
I answered your questions in an edit to my previous post just now. Sorry for any confusion/trouble. What I meant about passing by value was something along the lines of:
std::string str = _strStringName;parser.GetIntValuestr(str, "frame", iStopY);
{[JohnE, Chief Architect and Senior Programmer, Twilight Dragon Media{[+++{GCC/MinGW}+++{Code::Blocks IDE}+++{wxWidgets Cross-Platform Native UI Framework}+++

This topic is closed to new replies.

Advertisement