| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Заставить работать operator bool |
| Автор: borisbn 18.11.2013, 13:44 | ||||||||||
| Здравствуйте! Имеется такой код:
http://ideone.com/YBnKoU Оператор приведения к sqlite3_stmt* мне нужен, чтобы передавать экземпляр класса Stmt в C-шные функции. Типа такого:
Оператор приведения к bool мне нужен, чтобы после создания экземпляра проверять, всё ли в порядке. Типа такого:
На MinGW и g++ первая конструкция отрабатывает (и отрабатывает правильно), а вторая - нет. Т.е. не совсем нет. Оно компилируется, но вместо оператора приведения к bool вызывается первый оператор. Попытки явного приведения типа, такие как
ни к какому результату не привели. Вопрос: можно ли что-то сделать (доработать класс, задать ключи компиляции и т.д.), чтобы в (2) вызывался оператор bool, а в (1) - оператор приведения к sqlite3_stmt* ? Спасибо. P.S. Просьба не предлагать кидать исключение в конструкторе и не выделыватся, а написать ф-цию isOk(), которую и вызывать. Это и так понятно )) ------------------------------------------------------------------------ Как принято на некоторых других форумах, привожу решение от baldina в самом вопросе - нужно убрать const у operator bool:
|
| Автор: baldina 18.11.2013, 14:15 |
| http://ideone.com/n9oPXe Добавлено через 3 минуты и 12 секунд короче заведи себе 2 bool() - const и не const |
| Автор: vinter 18.11.2013, 14:23 | ||
По идее, должно хватить explicit для bool. Для кода выше нужен современный компилятор. |
| Автор: borisbn 18.11.2013, 14:30 |
| Вау... Как оперативно! Спасибо большое! Кстати, сначала подумал, что Вы меня дурачите - не увидел разницы между моим кодом и Вашим )) И ещё. Можно в догонку вопрос - Вы уже сталкивались с таким или ткнули пальцем в небо ? М.б. стандарт чётко говорит по этому поводу ? Если последнее, то не могли бы Вы подсказать, где именно ? Ещё раз спасибо. Закрываю Добавлено через 1 минуту и 24 секунды vinter, неа. explicit не спасает. |
| Автор: baldina 18.11.2013, 14:44 |
| все просто: компилятор использует const версию только для констант. про стандарт не скажу, лениво искать. |
| Автор: vinter 18.11.2013, 14:55 | ||||
Не может этого быть. При explicit sqlite3_stmt* компилятор не может использовать этот оператор в if
Компилятор не может использовать неконстантную версию для константы, но при обратной ситуации он не испытывает проблем. Более того, по идее, он должен предпочитать именно константную версию для lvalue Добавлено через 9 минут и 30 секунд http://stackoverflow.com/questions/11555950/distinguishing-between-user-defined-conversion-sequences-by-the-initial-standard хорошо этот вопрос раскрыт с указанием необходимых частей стандарта |
| Автор: vinter 18.11.2013, 15:46 | ||||||
Не обязательно: int * t{p}; Добавлено @ 15:54
Да, я не прав. Всё это регулируется следующей строкой стандарта([over.ics.rank]p3):
|
| Автор: borisbn 18.11.2013, 15:55 | ||||
| vinter, спасибо за ссылку на СОшку. Там aschepler очень подробно всё объяснил. Ключевым моментом является то, что для const-версии требуется на одно преобразование больше (Stmt -> const Stmt), а раз больше, то выбирается то, где меньше. Ещё раз всем спасибо. В реальности мне нужно не присваивать указателю, а передавать мой объект в функцию:
|
| Автор: borisbn 18.11.2013, 16:15 |
| На самом деле не т.к. для версии с указателем нужно его ещё потом к bool приводить. Ох и сложный же язык... |
| Автор: vinter 18.11.2013, 16:27 | ||
Нет, при перегрузке никаких двойных преобразований не рассматривается. У тебя, по сути две функции:
Теперь перечитываем вышеприведенную цитату. У нас как раз случай, что S1(operator sqlite3_stmt) больше подходит, т.к. S2(operator bool) имеет const. |
| Автор: baldina 18.11.2013, 18:00 | ||||||
да, user-defined преобразование лишь одно
а дальше все подходящие преобразования ранжируются, и выбирается лучшее. "на одно преобразование больше" это скорее фольклор, а не стандарт, хотя фольклор "правильный", т.к. длина преобразования неявно влияет на приоритет преобразования. Учитывая, что преобразование лишь одно, разная длина может означать только наличие преобразования квалификаторов (такое преобразование (surprise!) тоже является стандартным). Для квалификаторов кстати есть таблица
хотя наш случай в п. 13.3.3.2 указан явно, и даже имеется пример
ЗЫ. Кажется сам стал лучше понимать, откуда дети берутся что взялось |