为什么“操作符void”没有使用cast语法调用?

时间:2021-05-11 17:07:04

While playing with this answer by user GMan I crafted the following snippet (compiled with Visual C++ 9):

在使用GMan用户的回答时,我精心制作了以下代码片段(使用Visual c++ 9编译):

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

 Class object;
 static_cast<void>( object );
 (void)object;
 object.operator void();

after stepping over with the debugger I found out that casting to void doesn't invoke Class::operator void(), only the third invokation (with explicitly invoking the operator) actually invokes the operator, the two casts just do nothing.

在调试了调试器之后,我发现了对void的调用不调用类::操作符void(),只有第三个调用(使用显式调用操作符)实际上调用了操作符,这两个类型的转换什么都不做。

Why is the operator void not invoked with the cast syntax?

为什么操作符void没有被转换语法调用?

1 个解决方案

#1


27  

The technical reason why is found in §12.3.2:

技术原因存在于§12.3.2:

A conversion function is never used to convert a (possibly cv-qualified) object to the (possibly cv-qualified) same object type (or a reference to it), to a (possibly cv-qualified) base class of that type (or a reference to it), or to (possibly cv-qualified) void.

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

The rationale is (likely) to allow §5.2.9/4 to work:

基本原理是(可能)允许§5.2.9/4工作:

Any expression can be explicitly converted to type “cv void.” The expression value is discarded.

任何表达式都可以被显式转换为类型“cv void”。表达式值被丢弃。

(void)expr to suppose to do nothing for the resulting value of any expression, but if it called your conversion operator it wouldn't be discarding anything. So they ban the use of operator void in conversions.

(void)expr假定对任何表达式的结果值不做任何事情,但是如果它调用了您的转换操作符,它就不会丢弃任何东西。所以他们禁止在转换中使用运算符void。


Why not make it ill-formed to have the conversion-type-id be void? Who knows, but keep in mind it's not totally useless:

为什么不让conversion-type-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)

It is still technically potentially useful for something, so maybe that's rationale enough not to make it ill-formed.

它在技术上仍然可能对某些东西有用,所以这可能是足够的理由,不会使它变得糟糕。

#1


27  

The technical reason why is found in §12.3.2:

技术原因存在于§12.3.2:

A conversion function is never used to convert a (possibly cv-qualified) object to the (possibly cv-qualified) same object type (or a reference to it), to a (possibly cv-qualified) base class of that type (or a reference to it), or to (possibly cv-qualified) void.

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

The rationale is (likely) to allow §5.2.9/4 to work:

基本原理是(可能)允许§5.2.9/4工作:

Any expression can be explicitly converted to type “cv void.” The expression value is discarded.

任何表达式都可以被显式转换为类型“cv void”。表达式值被丢弃。

(void)expr to suppose to do nothing for the resulting value of any expression, but if it called your conversion operator it wouldn't be discarding anything. So they ban the use of operator void in conversions.

(void)expr假定对任何表达式的结果值不做任何事情,但是如果它调用了您的转换操作符,它就不会丢弃任何东西。所以他们禁止在转换中使用运算符void。


Why not make it ill-formed to have the conversion-type-id be void? Who knows, but keep in mind it's not totally useless:

为什么不让conversion-type-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)

It is still technically potentially useful for something, so maybe that's rationale enough not to make it ill-formed.

它在技术上仍然可能对某些东西有用,所以这可能是足够的理由,不会使它变得糟糕。