Assign std::string from an object using operator=
I'd really like to be able to assign a std::string
object from a DecoratedString
object that I'm writing.
class DecoratedString
{
private:
std::string m_String;
public:
DecoratedString(const std::string& initvalue)
: m_String(initvalue)
{
}
const std::string& ToString() const
{
return m_String;
开发者_开发百科 }
const std::string& operator=(const DecoratedString& rhs)
{
return rhs.ToString();
}
}
I've written a unit test to make sure this works:
void DecoratedStringTest::testAssignmentToString()
{
std::string expected("test");
DecoratedString sut(expected);
std::string actual;
actual = sut;
CPPUNIT_ASSERT_EQUAL(actual, sut.ToString());
}
However, the compiler says error: no match for 'operator=' in 'actual = sut'
. It then lists the overloaded operator= options from the standard library.
Why isn't the compiler finding the operator=
I defined?
EDIT:
So I guess I need a conversion operator, not an assignment operator. Huge thanks to the people that saw what I was trying to do and explained what I should do instead.
The operator = you have defined is for assigning decorated strings to other decorated strings and returning an std::string from that assignment.
What you want is a member "conversion operator" that automatically converts a decorated string to an std::string whenever required, like this:
operator std::string const &() const { return ToString(); }
That will also convert a decorated string automatically to a std::string const &
whenever one is needed (i.e. when comparing to an std::string, or passing a DecoratedString to a function which takes a std::string const &
).
The compiler is complaining about this line:
actual = sut;
which should be:
actual = sut.ToString();
Alternatively you should provide a cast operator to implicitly convert a DecoratedString
to a std::string
:
class DecoratedString
{
...
operator std::string() const
{
return ToString();
}
};
You're overloading the unary assignment operator that is intended for assigning a specific type to DecoratedString
and is supposed to return a reference to DecoratedString
so you can chain assignments. This operator is not designed to allow you to assign an object of DecoratedString
to a different datatype, but rather so you can assign an object that isn't necessarily a DecoratedString
to a DecoratedString
. It also gives you a well-defined function to handle any sort of specific processing that an assignment of your class might required (deep copy, for example).
You either have to call your ToString()
function or you'll have to create a conversion operator that can convert your DecoratedString
into a std::string
by implementing the following member function for DecoratedString
:
operator std::string () const;
This might or might not be a good idea as this conversion operator will be used implicitly by the compiler and might lead to unexpected behaviour.
As an aside, another reason why your operator overload is not working is that you're trying to overload a function by its return value, which is a big no-no in C++.
You got it backwards. The operator=
needs to be defined on the std::string
to be able to accept your object, not the class you are assigning from, but since you are dealing with the standard library you can't do that.
An alternative would be a streaming operator (as a free function):
std::string& operator<<( std::string& out, const your_class& yc )
{
out.assign( yc.to_string());
return out;
}
your_class myobj;
std::string str;
str << myobj;
Or just define regular streaming for std::ostream
and use std::stringstream
.
Edit:
Yet another option, as others noted, is the type conversion operator:
your_class::operator const std::string() const;
Modern practice though tells us it's not the greatest idea (temporaries, extra copies, surprises).
精彩评论