2010-01-31 2 views
22

Почему C++ требует, чтобы пользовательский оператор преобразования мог быть нестационарным членом? Почему не разрешено использовать автономные функции, как для других унарных операторов? Что-то вроде этого:оператор преобразования как автономная функция

operator bool (const std::string& s) { return !s.empty(); } 

ответ

6

Одна причины, я могу думать о том, чтобы предотвратить неявное преобразование применяется к вещам отливаемым. В вашем примере, если вы сказали:

bool("foo"); 

затем «Foo» будет неявно преобразован в строку, которая будет затем иметь явное преобразование булевых вы при условии, примененные к нему.

Это невозможно, если оператор bool является функцией-членом, поскольку неявные преобразования не применяются к *this. Это значительно уменьшает возможности для двусмысленности - двусмысленности обычно рассматриваются как «плохие вещи».

+0

Я не понимаю ваших аргументов. Пример, который вы дали, не является неявным преобразованием. С другой стороны, основной причиной определения оператора преобразования является использование неявного преобразования. – shura

+0

@shura Да, это так. «foo» неявно преобразуется в строку, которая затем явно преобразуется в bool. Я уточнил свой ответ, чтобы прояснить это. – 2010-01-31 13:58:31

+0

Нейл, теперь я вижу твою точку. – shura

0

Сохраняя оператор преобразования в классе, вы предоставляете автору элемента управления классом способ его преобразования (он не позволяет пользователям создавать неявные конверсий). В качестве исполнителя я бы счел это преимуществом, поскольку implicit conversions does have its issues

Есть разница в возможности передать один объект в качестве другого и иметь возможность пройти через функцию преобразования. Первый сообщает, что объект имеет данный тип, в то время как последний показывает новым читателям, что существует разница между этими двумя типами и что требуется преобразование.

+1

Это не дает никакого дополнительного контроля. Я могу (и, вероятно, должен) просто написать функцию ToBool() для преобразования. – 2010-01-31 14:06:13

+0

Это тоже :) Неявное преобразование - это нечто совсем иное, чем ToBool(). Если бы я мог сделать std :: string неявным конвертируемым символом char *, но, к счастью, Stroustrup et al. знал лучше. – daramarak

-2

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

Я думаю, что комитет по стандарту или Страуструп просто чувствовал, что это может быть слишком запутанным, если ему было разрешено вводить эти очень специальные поведения в классы извне.

Я полагаю, что лучший способ получить ответ - отправить электронное письмо автору.

+0

Ум, разве это не было принято задолго до того, как комитет по стандартам когда-либо встречался в первый раз? – sbi

+0

Или, может быть, Страуструп почувствовал это. Это просто спекуляция. Что общего у всех, так что все они должны быть членами? Я не вижу никаких технических причин, почему они должны (ОК, у присвоения будет техническая проблема, так как компилятор в противном случае синтезировал бы ее). – UncleBens

+0

грустно, потому что преобразование «из std :: string» в другие вещи является общим желанием –

-3

Неявные пользовательские конверсии в любом случае нахмурились. Не используйте их. Просто притворись, что их там нет. Не говоря уже о новых способах их внедрения.

В любом случае, я думаю, их нет, потому что они могут сделать достаточно неожиданных вещей. Включение нового заголовка, который вводит такое преобразование для класса, определенного где-то в другом месте, может привести к еще более запутывающим ошибкам.

+1

+1, хотя я бы сказал 's/user-defined //'. –

+0

Итак, когда C++ 0x позволяет использовать 'explicit' с операторами-литовыми, сохраняется ли ваш аргумент? Я мог представить некоторую полезность для автономных операторов трансляции, которые могут использоваться только с 'static_cast'. – jamesdlin

+0

Не то, чтобы я был большим поклонником неявного пользовательского преобразования. Я бы никогда не захотел неявно преобразовать строку в bool, как в моем примере. Но иногда они полезны. Например, возьмите std :: string (const char *). – shura

Смежные вопросы