为什么 NULL 会转换为 string*?
我看到了下面的代码:
class NullClass {
public:
template<class T> operator T*() const { return 0; }
};
const NullClass NULL;
void f(int x);
void f(string *p);
f(NULL); // converts NULL to string*, then calls f(string*)
Q1>我无法理解以下语句
template<class T> operator T*() const { return 0; }
特别是,operator T*()
的含义是什么?
Q2>为什么f(NULL)
最终触发了f(string*)
?
谢谢
I saw the following code:
class NullClass {
public:
template<class T> operator T*() const { return 0; }
};
const NullClass NULL;
void f(int x);
void f(string *p);
f(NULL); // converts NULL to string*, then calls f(string*)
Q1> I have problems to understand the following statement
template<class T> operator T*() const { return 0; }
Specially, what is the meaning of operator T*()
?
Q2> Why f(NULL)
is finally triggering the f(string*)
?
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
它是用户定义的转换运算符。它允许将
NullClass
类型的对象转换为任何指针类型。此类转换运算符通常会导致微妙的、意外的和有害的问题,因此在大多数情况下最好避免它们(当然,它们偶尔有用)。
NULL
的类型为NullClass
。它不能转换为int
,但用户定义的转换NullClass -> T*
可用于将其转换为string*
,因此选择void f(string*)
。请注意,这是可行的,因为只有一个
f
重载需要一个指针。如果您有两个重载,则调用将不明确,因为
NullClass -> T*
转换可以转换为int*
和float*
。It is a user-defined conversion operator. It allows an object of type
NullClass
to be converted to any pointer type.Such conversion operators can often lead to subtle, unexpected, and pernicious problems, so they are best avoided in most cases (they are, of course, occasionally useful).
NULL
is of typeNullClass
. It can't be converted to anint
, but the user-defined conversionNullClass -> T*
can be used to convert it to astring*
, sovoid f(string*)
is selected.Note that this works because there is only one overload of
f
that takes a pointer. If you had two overloads,the call would be ambiguous because the
NullClass -> T*
conversion can be converted to bothint*
andfloat*
.模板运算符 T*()
意味着对于任何T
都有从NullClass
到T*
的隐式转换。当您调用
f(NULL)
时,编译器需要决定使用哪个重载。由于两个重载都没有采用NullClass
类型的对象,因此它会查找存在哪些隐式转换。没有到int
的转换,但有一个到string*
的转换,因此应用转换并调用string*
重载。template<class T> operator T*()
means that there is an implicit conversion fromNullClass
toT*
for anyT
.When you're calling
f(NULL)
, the compiler needs to decide which overload to use. Since neither overload takes an object of typeNullClass
, it looks which implicit conversions exist. There is no conversion toint
, but there is one tostring*
, so the conversion is applied and thestring*
overload is called.operator Anything()
重载“cast”运算符。每当 NullClass 需要转换为 Anything 时,都会调用此函数,并使用结果。在您的情况下,Anything 是
T*
,其中 T 可以是任何类型(它是模板参数),这意味着 NullClass 支持转换为任何指针。因为 NullClass 可以转换为任何指针,包括
string*
。因此将使用f(string*)
版本。operator Anything()
overloads the "cast" operator. Whenever NullClass needs to be converted to Anything, this function will be called, and the result will be used.In your case, Anything is
T*
where T can be any type (it is a template parameter), meaning a NullClass supports casting to any pointers.Since NullClass can be cast into any pointers, including a
string*
. So thef(string*)
version will be used.它是一个隐式转换运算符。它使得它所属类型的对象可以隐式转换为目标类型
T*
。这个版本是一个特殊的版本,因为作为一个模板,它可以将该NullClass
的对象转换为任何指针类型。隐式转换不受欢迎是有充分理由的。它们有一个坏习惯,会在意想不到的时刻介入,使编译器调用重载函数的非预期版本。拥有模板化的隐式转换运算符尤其邪恶,因为模板化会增加可能性。
见上文。无法转换为
int
,因此隐式转换运算符启动并将NullClass
对象转换为请求的任何指针。我想这是故意的。通常您不希望将指针转换为整数,这就是该类隐式转换为任何指针的原因,但没有隐式转换为
int
的原因。NullClass
并没有那么糟糕,但它的NULL
实例纯粹是愚蠢的。一旦您包含定义NULL
宏(定义为0
,即整型常量)的众多标头中的任何一个,预处理器就会践踏所有源并替换NULL
与0
的每次使用。由于您无法避免包含此错误,因此此错误使整个类几乎毫无用处。It's an implicit conversion operator. It makes it possible to have objects of the type it belongs to implicit convert to the target type
T*
here. This version is a special one, since, being a template, it can convert an object of thatNullClass
to any pointer type.Implicit conversion are frowned upon for good reasons. They have the bad habit of kicking in at unexpected moments, making the compiler call an unintended version of an overloaded function. Having a templatized implicit conversion operator is especially evil because templatization multiplies the possibilities.
See above. There is no possible conversion to
int
, so the implicit conversion operator kicks in and converts anNullClass
object into any pointer requested.I suppose this is intended. Usually you don't want a pointer to be converted to an integer, which is why that class has an implicit conversion into any pointer, but none to
int
.That
NullClass
isn't all that bad, but theNULL
instance of it is pure stupidity. As soon as you include any of the many headers that define theNULL
macro (defined to be0
, i.e. an integer constant), the preprocessor will trample over all source and replace each usage ofNULL
with0
. Since you can't avoid to include this, this error renders the whole class pretty much useless.NuLLClass 提供了一个转换函数来转换为指针。当您调用
f(NULL)
时,它会尝试找到一种方法将 NULL 转换为 f 的有效参数。因为您可以对 NULL 调用
operator T*()
,所以它将使用 T=string。这满足了f(string *)
的需求。由于无法将 NULL 转换为 int,因此只有一个明确的选择来调用哪个函数。The NuLLClass provides a conversion function to convert to a pointer. When you call
f(NULL)
, it will try to find a way to convert NULL to a valid argument for f.Because you can call
operator T*()
on NULL, it will with T=string. This fulfills the demand forf(string *)
. Since there is no way to convert NULL to an int, there is only one clear choice of which function to call.它是类型
T*
的转换运算符。它允许诸如(T*)NULL
之类的操作。因为编译器会寻找参数和方法签名之间的最佳匹配,所以在本例中选择
template。 NullClass::operator T*()
,其中T=string
。It is a conversion operator to type
T*
. It allows operations such as(T*)NULL
.Because the compiler looks for the best match between the arguments and the method's signature, in this case choosing
template<typename T> NullClass::operator T*()
, whereT=string
.