Consider the following class, just as a simple example:
#include <iostream>
#include <string>
using namespace std;
class point {
public:
int _x{ 0 };
int _y{ 0 };
point() {}
point(int x, int y) : _x{ x }, _y{ y } {}
operator string() const
{ return '[' + to_string(_x) + ',' + to_string(_y) + ']'; }
friend ostream& operator<<(ostream& os, const point& p) {
// Which one? Why?
os << static_cast<string>(p); // Option 1
os << p.operator string(); // Option 2
return os;
}
};
Should one call a conversion operator directly, or rather just call static_cast
and let that do the job?
Those two lines will pretty much do exactly the same thing (which is to call the conversion operator), there's no real difference between their behavior as far as I can tell. So the real question here is whether that's true or not. Even though these seem the same to me, there could still be subtle differences that one might fail to pick up on.
So are there any practical differences between those approaches (including ones that might not apply to this example), other than the fact that the syntax for them different? Which one should be preferred and why?
So are there any practical differences between those approaches
In this case, not that I know of, behaviour wise.
(including ones that might not apply to this example)
static_cast<X>(instance_of_Y)
would also allow conversion if X
has a converting constructor for the type Y
. An explicit call to (possibly non-existent) conversion operator of Y
could not use the mentioned converting constructor. In this case of course, std::string
does not have a converting constructor for point
.
So, the cast is more generic and that is what I would prefer in general. Also "convert this object to type string
" is more meaningful than "call the operator string()
". But if for some very strange reason you want to avoid the converting constructor, then explicit call to conversion operator would achieve that.
No you never need to call the conversion operator member function directly.
If you use an instance of the class where a std::string
object is expected then the conversion operator will be called automatically by the compiler, as will it if you use e.g. static_cast
to cast an instance to std::string
.
Simple and stupid example:
void print_string(std::string const& s)
{
std::cout << s << '\n';
}
int main()
{
point p(1, 2);
print_string(p); // Will call the conversion operator
print_string(static_cast<std::string>(p)); // Will call the conversion operator too
}
The closest to call the function directly you will ever need is using something like static_cast
.
In your specific case, with the output operator, then you should use static_cast
. The reason is semantic and for future readers and maintainers (which might include yourself) of the code.
It will of course work to call the conversion member function directly (your option 2) but it loses the semantic information that says "here I'm converting the object to a string".
If the only use of the conversion operator is to use in the output operator, you might as well create a (private) function that takes the output stream reference as an argument, and writes directly to the stream, and call that function from the output operator.
来源:https://stackoverflow.com/questions/37629474/static-cast-vs-direct-call-to-conversion-operator