为什么 NULL 会转换为 string*?

发布于 2024-09-28 15:47:16 字数 488 浏览 13 评论 0原文

我看到了下面的代码:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

鯉魚旗 2024-10-05 15:47:16

运算符 T*() 的含义是什么?

它是用户定义的转换运算符。它允许将 NullClass 类型的对象转换为任何指针类型。

此类转换运算符通常会导致微妙的、意外的和有害的问题,因此在大多数情况下最好避免它们(当然,它们偶尔有用)。

为什么f(NULL)最终触发f(string*)

NULL 的类型为 NullClass。它不能转换为int,但用户定义的转换NullClass -> T* 可用于将其转换为 string*,因此选择 void f(string*)

请注意,这是可行的,因为只有一个 f 重载需要一个指针。如果您有两个重载,

void f(int*);
void f(float*);

则调用将不明确,因为 NullClass -> T* 转换可以转换为 int*float*

what is the meaning of operator T*()?

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).

Why f(NULL) is finally triggering the f(string*)?

NULL is of type NullClass. It can't be converted to an int, but the user-defined conversion NullClass -> T* can be used to convert it to a string*, so void 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,

void f(int*);
void f(float*);

the call would be ambiguous because the NullClass -> T* conversion can be converted to both int* and float*.

月牙弯弯 2024-10-05 15:47:16

模板运算符 T*() 意味着对于任何 T 都有从 NullClassT* 的隐式转换。

当您调用 f(NULL) 时,编译器需要决定使用哪个重载。由于两个重载都没有采用 NullClass 类型的对象,因此它会查找存在哪些隐式转换。没有到 int 的转换,但有一个到 string* 的转换,因此应用转换并调用 string* 重载。

template<class T> operator T*() means that there is an implicit conversion from NullClass to T* for any T.

When you're calling f(NULL), the compiler needs to decide which overload to use. Since neither overload takes an object of type NullClass, it looks which implicit conversions exist. There is no conversion to int, but there is one to string*, so the conversion is applied and the string* overload is called.

我只土不豪 2024-10-05 15:47:16
  1. operator Anything() 重载“cast”运算符。每当 NullClass 需要转换为 Anything 时,都会调用此函数,并使用结果。

    在您的情况下,Anything 是 T*,其中 T 可以是任何类型(它是模板参数),这意味着 NullClass 支持转换为任何指针。

  2. 因为 NullClass 可以转换为任何指针,包括 string*。因此将使用 f(string*) 版本。

  1. 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.

  2. Since NullClass can be cast into any pointers, including a string*. So the f(string*) version will be used.

奶茶白久 2024-10-05 15:47:16

Q1>我无法理解以下陈述

模板运算符 T*() const { 返回 0; }

特别是,运算符 T*() 的含义是什么?

它是一个隐式转换运算符。它使得它所属类型的对象可以隐式转换为目标类型T*。这个版本是一个特殊的版本,因为作为一个模板,它可以将该 NullClass 的对象转换为任何指针类型。
隐式转换不受欢迎是有充分理由的。它们有一个坏习惯,会在意想不到的时刻介入,使编译器调用重载函数的非预期版本。拥有模板化的隐式转换运算符尤其邪恶,因为模板化会增加可能性。

Q2>为什么 f(NULL) 最终触发 f(string*)?

见上文。无法转换为 int,因此隐式转换运算符启动并将 NullClass 对象转换为请求的任何指针。
我想这是故意的。通常您不希望将指针转换为整数,这就是该类隐式转换为任何指针的原因,但没有隐式转换为 int 的原因。


NullClass 并没有那么糟糕,但它的 NULL 实例纯粹是愚蠢的。一旦您包含定义 NULL 宏(定义为 0,即整型常量)的众多标头中的任何一个,预处理器就会践踏所有源并替换NULL0 的每次使用。由于您无法避免包含此错误,因此此错误使整个类几乎毫无用处。

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*()?

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 that NullClass 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.

Q2> Why f(NULL) is finally triggering the f(string*)?

See above. There is no possible conversion to int, so the implicit conversion operator kicks in and converts an NullClass 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 the NULL instance of it is pure stupidity. As soon as you include any of the many headers that define the NULL macro (defined to be 0, i.e. an integer constant), the preprocessor will trample over all source and replace each usage of NULL with 0. Since you can't avoid to include this, this error renders the whole class pretty much useless.

め七分饶幸 2024-10-05 15:47:16

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 for f(string *). Since there is no way to convert NULL to an int, there is only one clear choice of which function to call.

仙女 2024-10-05 15:47:16

特别是,运算符 T*() 的含义是什么?

它是类型 T* 的转换运算符。它允许诸如(T*)NULL之类的操作。

Q2>为什么 f(NULL) 最终触发 f(string*)?

因为编译器会寻找参数和方法签名之间的最佳匹配,所以在本例中选择 template。 NullClass::operator T*(),其中 T=string

Specially, what is the meaning of operator T*()?

It is a conversion operator to type T*. It allows operations such as (T*)NULL.

Q2> Why f(NULL) is finally triggering the f(string*)?

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*(), where T=string.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文