Почему "оператор void" не вызывается с синтаксисом броска?

Во время игры этот ответ от пользователя пользователя GMan я создал следующий фрагмент (скомпилированный с Visual С++ 9 ):

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

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

после перехода с отладчиком я обнаружил, что кастинг на void не вызывает Class::operator void(), на самом деле вызывает вызов только третий вызов (с явным вызовом оператора), эти две команды просто ничего не делают.

Почему operator void не вызывается с синтаксисом cast?

Ответы

Ответ 1

Техническая причина, о которой говорится в §12.3.2:

Функция преобразования никогда не используется для преобразования (возможно, cv-квалифицированного) объекта к (возможно, cv-квалифицированному) одному типу объекта (или ссылке на него) к базовому классу (возможно, cv-qualit) этого тип (или ссылку на него), или (возможно, cv-qualified) void.

Обоснование (вероятно), чтобы разрешить работу §5.2.9/4:

Любое выражение может быть явно преобразовано в тип "cv void". Значение выражения отбрасывается.

(void)expr, чтобы ничего не делать для результирующего значения любого выражения, но если он назвал ваш оператор преобразования, он ничего не отбрасывал. Поэтому они запрещают использование operator void в конверсиях.


Почему бы не сделать его плохо сформированным, чтобы идентификатор типа преобразования был 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)

Это по-прежнему технически потенциально полезно для чего-то, поэтому, возможно, это обоснование достаточно, чтобы не сделать его плохо сформированным.