Generating a Unique (numbered) Name in C++

Started by
16 comments, last by M2tM 15 years, 3 months ago
Quote:Original post by jyk
Quote:Original post by M2tM
Not everyone wants to include boost just to cast from an int to a string.


Keep in mind that you don't really have to 'include Boost' to use lexical_cast; it's header only, so all you really have to do is include a single header file (if that's what you meant by 'include Boost', then never mind, although it does seem somewhat limiting to deprive oneself of such a simple and useful tool due to not wanting to include a few headers).


Right.

So essentially M2tM, you're spending time to write a (poor) copy of the wheel so you than can then include that header everywhere, instead of downloading a single well vetted file and include that everywhere.

It doesn't even really matter if your code is perfect, it's always a worse choice.

Advertisement
Whilst using boost::lexical_cast for casting an integer to a string is clearly superior to writing a casting function in terms of std::stringstream. It does seem to me that the OP's actual objective isn't necessarily that task. The OP just wishes to append an integer to the end of a string and, although I would still favour lexical_cast for the optimisations, this is the sort of thing that string-streams are classically used/good for:

#include <string>#include <utility>#include <map>#include <sstream>#include <algorithm>#include <iostream>#include <iterator>class enumerate_name{private:    typedef std::map<std::string, int> usecount_map;    usecount_map usecounts;public:    std::string operator()(const std::string & name)    {        std::pair<usecount_map::iterator, bool> result =            usecounts.insert(std::make_pair(name, 0));        if (result.second) return name;                std::ostringstream ss(name, std::ostringstream::ate);        ss << ++result.first->second;        return (*this)(ss.str());    }};int main(){    const char * names[] = { "item", "item", "item", "item1" };    std::transform(names,                   names + 4,                   std::ostream_iterator<std::string>(std::cout, " "),                   enumerate_name());}


[Edited by - dmatter on January 11, 2009 12:23:35 PM]
Quote:Original post by dmatter
Whilst using boost::lexical_cast for casting an integer to a string is clearly superior to writing a casting function in terms of std::stringstream. It does seem to me that the OP's actual objective isn't necessarily that task. The OP just wishes to append an integer to the end of a string and, although I would still favour lexical_cast for the optimisations, this is the sort of thing that string-streams are classically used/good for:

*** Source Snippet Removed ***

Just a minor (admittedly pedantic :-) detail for the sake of portability: note that std::ostream_iterator is defined in the <iterator> header.
Quote:Original post by Metsan
Just a minor (admittedly pedantic :-) detail for the sake of portability: note that std::ostream_iterator is defined in the <iterator> header.
Thanks, I had copied the includes in afterwards and missed one off the bottom. [smile]
Quote:Original post by Telastyn
It doesn't even really matter if your code is perfect, it's always a worse choice.
I think worse is a relative term here. If you know what you are converting from and what you are converting to, there may be preferable solutions. Preferable, in my case, was getting rid of a warning cause by boost::lexical_cast. Time for a story:

I try to use boost::lexical_cast whenever I can, but I ended up getting warnings when casting from something to std::string. I'm building a static library that people include in their projects, and the problem was that the warning wasn't showing when I built the library, but it would show up when customers tried to use the library in their projects. It wasn't a major warning (it just said a return statement in boost::lexical_cast was unreachable because of a throw statement), but it's not acceptable for me to be giving people libraries which will produce warnings in their projects. So I wrote my own toString() function that used std::ostringstream to convert to std::string. It's simple and doesn't do any real error checking, but since I know I'm only using to to convert an int or float to a std::string, I consider it to be worth it to get rid of that warning.

Moral of the story: use boost::lexical_cast if possible, but be aware of alternate solutions should the necessity ever arise.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
Thanks guys. I was generally aware of Boost, but not any of the libraries in particular. It looks like something I should read up on more. There could be some other things in there which I'll find useful. Having been programming mainly in BlitzMax lately, I do like the look of Boost::Foreach.

I'm just getting back into C++ after a very long absence ( and I was only a beginner then ) so I'm trying to avoid anything which might have memory useage requirements I'm not aware of. I read about StringStream as a solution, but since I've never used it, I wasn't sure if there were any implications as regards freeing it after using it. It looks from the examples you've posted as though it's allocated on the stack and any memory used is returned automatically when you finish it.

I think I'll go with Boost::Lexical_Cast. I'd only seen boost before in BlitzMax, and therefore I wasn't aware that it could be included on a header by header basis. That fits very well with the kind of programmer I am, so that seems like a good solution.

Thanks for all the advice.
Quote:Original post by sybixsus
I do like the look of Boost::Foreach.
There is also a std::for_each, it's not as nice to use as BOOST_FOREACH for the time being, but I imagine it might make the boost version redundant in the next C++ standard where it's usage pattern is greatly simplified.

Quote:I read about StringStream as a solution, but since I've never used it, I wasn't sure if there were any implications as regards freeing it after using it.
Nope, in fact, there rarely are any occasions where you need to manually free memory from standard library components; they all employ the RAII idiom (Resource Acquisition is Initialisation) so they clean up after themselves, thus your observation...

Quote:It looks from the examples you've posted as though it's allocated on the stack and any memory used is returned automatically when you finish it.

... is correct [smile]
Thanks for the info. I didn't spend a long time writing that obviously, and I haven't used it for much other than basic conversions from built in number types to string and back. I'll get boost::lexical_cast now that I'm aware of the issues.
_______________________"You're using a screwdriver to nail some glue to a ming vase. " -ToohrVyk

This topic is closed to new replies.

Advertisement