Suppose I want to throw
with a string containing information about some object, but the object implementation only has an overload for the stream operator (<<
) rather than a cast to string. I want to do something like this:
throw std::runtime_error("Error, encountered invalid value " + x);
where x
is an instance of a type which has (<<
) overloaded. The above does not work, however, because the +
is not overloaded to a type compatible with const char*
. If x
were a string (or castable to a string) it would work, but instead I have to do this:
std::stringstream s;
s << "Error, encountered invalid value " << x;
throw std::runtime_error(s.str());
How can I get something as concise as the first example without adding any overloads or custom functions. Does the Standard Library provide some features that will help here?
To get cout to accept a Date object after the insertion operator, overload the insertion operator to recognize an ostream object on the left and a Date on the right. The overloaded << operator function must then be declared as a friend of class Date so it can access the private data within a Date object.
To make this statement compile, we must overload '+' in a class of 'ob1' or make '+' a global function. The operators '<<' and '>>' are called like 'cout << ob1' and 'cin >> ob1'.
Overloading Binary Operators Suppose that we wish to overload the binary operator == to compare two Point objects. We could do it as a member function or non-member function. To overload as a member function, the declaration is as follows: class Point { public: bool operator==(const Point & rhs) const; // p1.
No we cannot overload integer or float types because overloading means to change the working of existing operators or make them to work with objects int is single member not an object.
You can delegate to a function:
template <typename T>
std::string stream(const T& x) {
std::ostringstream ss;
ss << x;
return ss.str();
}
throw std::runtime_error("Error..." + stream(x));
Which is also what boost::lexical_cast
does:
throw std::runtime_error("Error..." + boost::lexical_cast<std::string>(x));
Or you can use a temporary stream, which involves having to do a cast since operator<<
conventionally returns just a basic_ostream<char>&
:
throw std::runtime_error(
static_cast<std::ostringstream&&>(std::ostringstream{} << "Error..." << x)
.str() );
Or you can wrap that logic into a separate type which, when streamed, converts the result to a string
, for amusement's sake:
struct ToStrT {
friend std::string operator<<(std::ostream& os, ToStrT ) {
return static_cast<std::ostringstream&&>(os).str();
}
};
constexpr ToStrT ToStr{};
throw std::runtime_error(std::ostringstream{} << "Error..." << x << ToStr);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With