是否可以在C ++中覆盖(C风格)强制转换?
假设我有代码
double x = 42;
int k = (int)x;
我可以让第二行的演员表执行我写的一些代码吗?像
这样的东西// I don't know C++
// I have no idea if this has more syntax errors than words
operator (int)(double) {
std::cout << "casting from double to int" << std::endl;
}
我问的原因是因为问题"Is there any way to get gcc or clang to warn on explicit casts?"和我的建议。
答案 0 :(得分:4)
§12.3.1/ 1“类对象的类型转换可以由构造函数和转换函数指定。这些转换称为用户定义的转换,用于隐式类型转换(第4节),用于初始化(8.5) ,以及显式类型转换(5.4,5.2.9)。“
是的,我们可以进行转化,但前提是一方或双方是用户定义的类型,因此我们无法为double
提供int
。
struct demostruct {
demostruct(int x) :data(x) {} //used for conversions from int to demostruct
operator int() {return data;} //used for conversions from demostruct to int
int data;
};
int main(int argc, char** argv) {
demostruct ds = argc; //conversion from int to demostruct
return ds; //conversion from demostruct to int
}
正如Robᵩ指出的那样,您可以将explicit
关键字添加到其中任何一个转化函数中,这需要用户在代码中使用(demostruct)argc
或(int)ds
显式转换它们而不是让他们隐式转换。如果转换为相同类型或从同一类型转换,通常最好将其中一个或两个作为explicit
,否则可能会出现编译错误。
答案 1 :(得分:3)
是的,但仅适用于您自己的类型。看看这个:
#include <iostream>
struct D {
// "explicit" keyword requires C++11
explicit operator int() { std::cout << __FUNCTION__ << "\n"; }
};
int main () {
int i;
D d;
//i = d;
i = (int)d;
}
因此,您无法创建double::operator int()
,但可以创建MyDouble::operator int()
。
答案 2 :(得分:2)
您不能为内置类型重载运算符,但您可以为用户定义的类型编写转换运算符:
struct Double {
double value;
operator int() const {
shenanigans();
return value;
}
};
由于您的问题源于需要在代码中查找显式强制类型转换,因此请注意C ++具有显式的强制转换运算符。这些不仅比C风格的演员阵容更清晰,而且非常易于搜索:
static_cast<T>(x) // Cast based on static type conversion.
dynamic_cast<T>(x) // Cast based on runtime type information.
const_cast<T>(x) // Add or remove const or volatile qualification.
reinterpret_cast<T>(x) // Cast between unrelated pointer and integral types.
答案 3 :(得分:1)
转换为其他类型是C ++中的可重载运算符(some examples here),但这一事实对您没有帮助。
Stroustrup wanted语言是可扩展的,但不可变。因此,重载操作符只会将操作扩展到新类型,但是您无法重新定义任何旧类型的操作。
“但是,为了避免荒谬,(仍然)不允许为内置类型的内置运算符提供新的含义。因此,语言仍然可扩展但不可变。 “