为什么使用强制语法不调用"operator void"?

sha*_*oth 40 c++ casting operator-overloading operators

用户GMan使用此答案时,我制作了以下代码段(使用Visual C++ 9编译):

 class Class {
 public:
     operator void() {}
 };

 Class object;
 static_cast<void>( object );
 (void)object;
 object.operator void();
Run Code Online (Sandbox Code Playgroud)

在使用调试器踩到后,我发现转换为void不调用Class::operator void(),只有第三个invokation(显式调用运算符)实际上调用了运算符,两个转换只是什么都不做.

为什么operator void不使用强制语法调用?

GMa*_*ckG 30

技术原因见§12.3.2:

转换函数从不用于将(可能是cv限定的)对象转换为(可能是cv限定的)相同的对象类型(或对它的引用),转换为该类型的(可能是cv限定的)基类(或引用它)或(可能是cv-qualified)void.

理由是(可能)允许§5.2.9/ 4工作:

可以将任何表达式显式转换为"cv void"类型.表达式值将被丢弃.

(void)expr假设对任何表达式的结果值都不做任何事情,但如果它调用了你的转换运算符,它就不会丢弃任何东西.所以他们禁止使用operator void转换.


为什么不将转换类型ID变为格式错误void?谁知道,但请记住,这并非完全没用:

struct foo
{
    operator void()
    {
        std::cout << "huh?" << std::endl;
    }

};

typedef void (foo::*void_function)();

foo f;
void_function func = &foo::operator void;

(f.*func)(); // prints "huh"
f.operator void(); // also does (which you knew)
Run Code Online (Sandbox Code Playgroud)

它在技术上仍然可能对某些东西有用,所以也许这个理由足以让它变得不合理.

  • *"为什么不让转换类型id为'void`使其形成错误?"*也许是因为`void`可能隐藏在typedef或template参数后面? (6认同)