static_cast 还是直接调用转换运算符?
static_cast vs. direct call to conversion operator?
考虑以下 class,作为一个简单的例子:
#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;
}
};
应该直接调用转换运算符,还是只调用 static_cast
然后让它完成工作?
这两行将做几乎完全相同的事情(即调用转换运算符),据我所知,它们的行为之间没有真正的区别。所以这里真正的问题是这是否正确。尽管这些对我来说看起来是一样的,但仍然存在一些细微的差异,人们可能无法理解。
除了语法不同之外,这些方法之间是否存在任何实际差异(包括可能不适用于此示例的方法)?应该首选哪一个?为什么?
不,您永远不需要直接调用转换运算符成员函数。
如果您使用 class 的实例,其中需要 std::string
对象,那么编译器将自动调用转换运算符,如果您使用例如static_cast
将实例转换为 std::string
。
简单愚蠢的例子:
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
}
最接近直接调用函数的方法是使用类似 static_cast
.
的方法
在您的特定情况下,使用输出运算符,那么您应该使用 static_cast
。原因是 语义 以及代码的未来读者和维护者(可能包括您自己)。
当然可以直接调用转换成员函数(您的选项 2),但它会丢失表示 "here I'm converting the object to a string".
的语义信息
如果转换运算符的唯一用途是在输出运算符中使用,您不妨创建一个(私有)函数,将输出流引用作为参数,并直接写入流,并调用来自输出运算符的函数。
So are there any practical differences between those approaches
在这种情况下,据我所知,行为明智。
(including ones that might not apply to this example)
如果 X
具有类型 Y
的转换构造函数,static_cast<X>(instance_of_Y)
也将允许转换。对 Y
的(可能不存在的)转换运算符的显式调用无法使用提到的转换构造函数。当然,在这种情况下,std::string
没有 point
.
的转换构造函数
因此,演员表更通用,这也是我总体上更喜欢的。另外 "convert this object to type string
" 比 "call the operator string()
" 更有意义。但是如果出于某种非常奇怪的原因你想避免转换构造函数,那么显式调用转换运算符就可以实现这一点。
考虑以下 class,作为一个简单的例子:
#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;
}
};
应该直接调用转换运算符,还是只调用 static_cast
然后让它完成工作?
这两行将做几乎完全相同的事情(即调用转换运算符),据我所知,它们的行为之间没有真正的区别。所以这里真正的问题是这是否正确。尽管这些对我来说看起来是一样的,但仍然存在一些细微的差异,人们可能无法理解。
除了语法不同之外,这些方法之间是否存在任何实际差异(包括可能不适用于此示例的方法)?应该首选哪一个?为什么?
不,您永远不需要直接调用转换运算符成员函数。
如果您使用 class 的实例,其中需要 std::string
对象,那么编译器将自动调用转换运算符,如果您使用例如static_cast
将实例转换为 std::string
。
简单愚蠢的例子:
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
}
最接近直接调用函数的方法是使用类似 static_cast
.
在您的特定情况下,使用输出运算符,那么您应该使用 static_cast
。原因是 语义 以及代码的未来读者和维护者(可能包括您自己)。
当然可以直接调用转换成员函数(您的选项 2),但它会丢失表示 "here I'm converting the object to a string".
的语义信息如果转换运算符的唯一用途是在输出运算符中使用,您不妨创建一个(私有)函数,将输出流引用作为参数,并直接写入流,并调用来自输出运算符的函数。
So are there any practical differences between those approaches
在这种情况下,据我所知,行为明智。
如果(including ones that might not apply to this example)
X
具有类型 Y
的转换构造函数,static_cast<X>(instance_of_Y)
也将允许转换。对 Y
的(可能不存在的)转换运算符的显式调用无法使用提到的转换构造函数。当然,在这种情况下,std::string
没有 point
.
因此,演员表更通用,这也是我总体上更喜欢的。另外 "convert this object to type string
" 比 "call the operator string()
" 更有意义。但是如果出于某种非常奇怪的原因你想避免转换构造函数,那么显式调用转换运算符就可以实现这一点。