Jump to content
  • Advertisement
Sign in to follow this  
paic

operator + with various parameter types

This topic is 4869 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

Hi, Here's a bit of code I'm currently using :
// the AMString class is just a wrapper class around std::string, so I can
// just replace my own string class by a one using std::string, without
// changing the rest of the code

// in the .h
class AMString
{
protected:
   std::string m_str;

public:
   AMString(void);
   // ...

   // operators +
   AMString operator + (const float value);
   AMString operator + (const int value);
   // ...

// ...
};

// in the .cpp :
AMString AMString::operator + (const float value)
{
   std::stringstream  ss;
   std::string        str;
   ss << m_str;
   ss << value;
   ss >> str;
   return(AMString(str));
}

AMString AMString::operator + (const int value)
{
   std::stringstream  ss;
   std::string        str;
   ss << m_str;
   ss << value;
   ss >> str;
   return(AMString(str));
}



2 questions : - Is it the correct way of concantenating a number to a std::string ? - The code for floats and ints is exactly the same. Is there a way to specify an operator that would accept any type of parameter, so that I only have on operator + defined which would accept floats, ints, etc. ?? Thx for any help

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by paic
Hi,

Here's a bit of code I'm currently using :

*** Source Snippet Removed ***

2 questions :

- Is it the correct way of concantenating a number to a std::string ?

There are a few variants, but all are pretty much based on stringstreams in one way or another. Your way is OK.

Quote:
Original post by paic
- The code for floats and ints is exactly the same. Is there a way to specify an operator that would accept any type of parameter, so that I only have on operator + defined which would accept floats, ints, etc. ??


Thx for any help

Can be solved with templates.

template<typename T> AMString operator + (T value);

template<typename T> AMString AMString::operator + (T value)
{
std::stringstream ss;
std::string str;
ss << m_str;
ss << value;
ss >> str;
return(AMString(str));
}

Now you can use operator + with any datatype that can be passed to an ostream with operator <<.

Share this post


Link to post
Share on other sites
That won't work with strings that contain spaces. I also recommend making operator+ a non-member function implemented in terms of a member operator+=. This has the dual benefits of having your implementation in only one place (operator+=) and allowing type conversions on both arguments of operator+. You probably want something like:
#include <iostream>
#include <sstream>
#include <string>

class AMString
{

public:

AMString(std::string const & s)
:
m_str(s)
{
}

std::string str() const
{
return m_str;
}

AMString & operator+=(AMString const & value);

template < typename Type >
AMString & operator+=(Type const & value);

private:

std::string m_str;

};

AMString & AMString::operator+=(AMString const & value)
{
m_str += value.m_str;
return *this;
}

template < typename Type >
AMString & AMString::operator+=(Type const & value)
{
std::ostringstream ss;
ss << value;
m_str += ss.str();
return *this;
}

AMString operator+(AMString lhs, AMString const & rhs)
{
return lhs += rhs;
}

template < typename Type >
AMString operator+(AMString lhs, Type const & rhs)
{
return lhs += rhs;
}

template < typename Type >
AMString operator+(Type const & lhs, AMString const & rhs)
{
// possibly not the most efficient implementation, but saved me having to write more code
return (AMString("") += lhs) += rhs;
}

int main()
{
AMString str1("Hello");
str1 += " World!";
std::cout << (AMString("Hello") + AMString(" World!")).str() << '\n';
std::cout << str1.str() << '\n';
std::cout << (str1 + ' ' + 2).str() << '\n';
std::cout << (1 + (": " + str1)).str() << '\n';
}


Those templates will allow concatenation to an AMString of any class which has an operator<< which can be called for an output stream.

Enigma

Share this post


Link to post
Share on other sites
Oh, and I forgot, when dealing with templates you can't separate declaration and definition as you have in your original code. You must put the function definition in the header aswell.

edit: Some suggestions by Enigma I didn't think about, so focus on his reply instead of mine.

Share this post


Link to post
Share on other sites
Ah, I didn't know that you could have a template method in a non-template class. That will help a lot, thx ^^

And for the whitespace, yes, I just came accross a post here ^^
I replaced "ss >> str; return(AMString(str));" by "return(AMString(ss.str()))";
It saves 1 line of code and don't stop at the whitespaces.


@Enigma : I already use the operator += in my operators +. In the code snippet, it was just an example. In my final code, operator + uses operator +=. But I don't understand what you mean by "and allowing type conversions on both arguments of operator+"

Share this post


Link to post
Share on other sites
By "allowing type conversion on both arguments" I mean the following:
#include <string>

class Widget1
{

public:

Widget1(std::string const & string);
Widget1 operator+(Widget1 const & w);

};

class Widget2
{

public:

Widget2(std::string const & string);

};

Widget2 operator+(Widget2 const & lhs, Widget2 const & rhs);

int main()
{
Widget1 w1_1("widget1 1");
Widget2 w2_1("widget2 1");
std::string extra = "extra";

// OK, compiler constructs a temporary Widget1 object from extra and
// calls Widget1::operator+(Widget1 const &)
// type conversion on second parameter
Widget1 w1_2 = w1_1 + extra;

// ERROR, compiler will not perform type conversions on the "this"
// parameter of member functions
// no type conversion on first parameter
Widget1 w1_3 = extra + w1_1;

// OK, compiler constructs a temporary Widget2 object from extra and
// calls operator+(Widget2 const &, Widget2 const &)
// type conversion on second parameter
Widget2 w2_2 = w2_1 + extra;

// OK, compiler constructs a temporary Widget2 object from extra and
// calls operator+(Widget2 const &, Widget2 const &)
// type conversion on first parameter
Widget2 w2_3 = extra + w2_1;
}

Of course, for your situation the chances of having a class which has an implicit conversion to AMString but does not have a operator<< usable with output streams are pretty slim, but since there are no disadvantages to using a non-member operator+ I would still use them for consistency.

Enigma

Share this post


Link to post
Share on other sites
Ok, I've tried what you said Enigma. But I have problems with the templates. I need to declare and define the template operators + in the .h, but if I do that, I have plenty of "blablah already defined in blahblah.obj" errors :/
It only cause problems with global operator +.


EDIT : ok, was my mistake, I made a typo ^^''

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!