Jump to content
  • Advertisement
Sign in to follow this  
Lucas W

variable argument list + std::string

This topic is 3739 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello all! Im sorry about the post spam. My laptop totally went crazy and I got script errors and such from GameDev.net. The question is (as some people already figured out) how I could get around the fact that I cant use std::string with a variable argument list. Im using this list for a logfunction, and I would need it pretty bad. It works just like sprintf and it works like a charm except for one thing. I would like to pass a std::string variable to the list and then read it somehow. Is this possible?

//Function
void Log(std::string format, ...)
{
   //do stuff.
   
   char *p = va_arg(list, char*);
   
   log << p;

   //do some more stuff.
}

//Usage
Log("My name is %s", "Lucas"); //Works

std::string name = "Lucas";
Log("My name is %s", name); //Does obviously not work.


So is there any way to get around this? (Changing the variable to a char pointer is not an option). Thanks, and sorry for the mess. [Edited by - Lucas W on July 20, 2008 6:20:07 PM]

Share this post


Link to post
Share on other sites
Advertisement
I think we can guess the question, though. The question is probably why std::strings won't work via an ellipsis. The answer is that it has to do with the way variable argument lists work. The real fix to avoiding this problem is not using variable argument lists. Instead, using something like boost::format will make your life much easier.

Share this post


Link to post
Share on other sites
The c_str() method returns a const char pointer, that can be passed into an ellipsis.

However, I agree that avoiding variable argument lists altogether is the better approach, because they are not type safe at all.

Share this post


Link to post
Share on other sites
Quote:
Original post by Rattenhirn
The c_str() method returns a const char pointer, that can be passed into an ellipsis.

However, I agree that avoiding variable argument lists altogether is the better approach, because they are not type safe at all.


I was a bit vague. I meant as part of the format string. You can't have the format string be a std::string. I was just guessing that that was his problem, since it happened to me, once, a while back. That was when I swore of using varargs -- too many risks. Other than, we're in agreement, which is good. [smile]

Share this post


Link to post
Share on other sites
Please take a look again at my problem and tell me how I should solve this :)

What is this boost::format and how do I use it?

Share this post


Link to post
Share on other sites

template<typename T>
Log &operator<<(const T &rhs)
{
// do stuff

log << rhs;

// do some more stuff

return *this;
}

std::string name = "Lucas";
log << "my name is " << name;


Why are you using a C idiom in C++?

Share this post


Link to post
Share on other sites
Quote:
Original post by Lucas W
Please take a look again at my problem and tell me how I should solve this :)

What is this boost::format and how do I use it?


The parameter for the format string can't be a std::string or any C++ object. It has to be a raw string. So to be safe it should look like this:


//Function
void Log(const char* format, ...)
{
//do stuff.

char *p = va_arg(list, char*);

log << p;

//do some more stuff.
}

//Usage
Log("My name is %s", "Lucas"); //Works

std::string name = "Lucas";
Log("My name is %s", name.c_str()); // Convert to raw string when passing in




But, as mentioned, you lose type safety. Another option is to do this:


//Function
void Log(const std::string& str)
{
//do stuff.

log << str;

//do some more stuff.
}

using boost::format;
using boost::str;

//Usage
Log(str(format("My name is %s") % "Lucas")); //Works

std::string name = "Lucas";
Log(str(format("My name is %s") % name)); // Works with C++ string




Boost format gives you a more typesafe way to do your typical printf-like string operations. For more information, check here: http://www.boost.org/doc/libs/1_35_0/libs/format/doc/format.html

Finally, I did learn something new from this post. When I said the format string can't be a std::string, I believe I had tried this:


void Log(const std::string& format, ...)
{
...
}




Which cannot work. Hadn't occurred to me that passing by value would allow it to work. Either way, ultimately another nasty feature of var args. It's not important, though, since I refuse to use var args anymore, anyway. [smile]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!