![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| borisbn |
|
||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
Здравствуйте!
Имеется такой код:
http://ideone.com/YBnKoU Оператор приведения к sqlite3_stmt* мне нужен, чтобы передавать экземпляр класса Stmt в C-шные функции. Типа такого:
Оператор приведения к bool мне нужен, чтобы после создания экземпляра проверять, всё ли в порядке. Типа такого:
На MinGW и g++ первая конструкция отрабатывает (и отрабатывает правильно), а вторая - нет. Т.е. не совсем нет. Оно компилируется, но вместо оператора приведения к bool вызывается первый оператор. Попытки явного приведения типа, такие как
ни к какому результату не привели. Вопрос: можно ли что-то сделать (доработать класс, задать ключи компиляции и т.д.), чтобы в (2) вызывался оператор bool, а в (1) - оператор приведения к sqlite3_stmt* ? Спасибо. P.S. Просьба не предлагать кидать исключение в конструкторе и не выделыватся, а написать ф-цию isOk(), которую и вызывать. Это и так понятно )) ------------------------------------------------------------------------ Как принято на некоторых других форумах, привожу решение от baldina в самом вопросе - нужно убрать const у operator bool:
Это сообщение отредактировал(а) borisbn - 18.11.2013, 14:33 -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||||||||
|
|||||||||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
http://ideone.com/n9oPXe
Добавлено через 3 минуты и 12 секунд короче заведи себе 2 bool() - const и не const |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
По идее, должно хватить explicit для bool. Для кода выше нужен современный компилятор. Это сообщение отредактировал(а) vinter - 18.11.2013, 14:23 |
|||
|
||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
Вау... Как оперативно! Спасибо большое!
Кстати, сначала подумал, что Вы меня дурачите - не увидел разницы между моим кодом и Вашим )) И ещё. Можно в догонку вопрос - Вы уже сталкивались с таким или ткнули пальцем в небо ? М.б. стандарт чётко говорит по этому поводу ? Если последнее, то не могли бы Вы подсказать, где именно ? Ещё раз спасибо. Закрываю Добавлено через 1 минуту и 24 секунды vinter, неа. explicit не спасает. -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
все просто: компилятор использует const версию только для констант.
про стандарт не скажу, лениво искать. |
|||
|
||||
| vinter |
|
||||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
Не может этого быть. При explicit sqlite3_stmt* компилятор не может использовать этот оператор в if
Компилятор не может использовать неконстантную версию для константы, но при обратной ситуации он не испытывает проблем. Более того, по идее, он должен предпочитать именно константную версию для lvalue Добавлено через 9 минут и 30 секунд Здесь хорошо этот вопрос раскрыт с указанием необходимых частей стандарта |
||||
|
|||||
| baldina |
|
||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
почему? Stmt преобразуется в sqlite3_stmt* (implicit user-defined conversion), указатель - в bool (implicit standard conversion).
раз уж полез в стандарт, отвечу на вопрос borisbn: в стандарте нет неявного преобразования из const в неконстантное значение. это логично: иначе вообще зачем константы. представьте, что operator bool() родит побочный эффект. тогда результат выполнения в результате неявного преобразования непредсказуем. Добавлено через 4 минуты и 50 секунд а, я читаю неправильно все верно. если оператор должен вызываться явно, в неявном преобразовании он не участвует. Добавлено через 8 минут и 21 секунду ну это, увы, не так, хотя иногда кажется удобным: на одно преобразование больше получается. и раз хочется, что бы оба преобразования выполнялись неявно, нужна неконстантная версия operator bool() Добавлено через 10 минут и 17 секунд http://ideone.com/CMl6xv к указателю в этом случае приходится приводить явно |
||||||||
|
|||||||||
| vinter |
|
||||||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
Не обязательно: int * t{p}; Добавлено @ 15:54
Да, я не прав. Всё это регулируется следующей строкой стандарта([over.ics.rank]p3):
Это сообщение отредактировал(а) vinter - 18.11.2013, 15:59 |
||||||
|
|||||||
| borisbn |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
vinter, спасибо за ссылку на СОшку. Там aschepler очень подробно всё объяснил. Ключевым моментом является то, что для const-версии требуется на одно преобразование больше (Stmt -> const Stmt), а раз больше, то выбирается то, где меньше.
Ещё раз всем спасибо. В реальности мне нужно не присваивать указателю, а передавать мой объект в функцию:
-------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||
|
|||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
На самом деле не
т.к. для версии с указателем нужно его ещё потом к bool приводить. Ох и сложный же язык... -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
Нет, при перегрузке никаких двойных преобразований не рассматривается. У тебя, по сути две функции:
Теперь перечитываем вышеприведенную цитату. У нас как раз случай, что S1(operator sqlite3_stmt) больше подходит, т.к. S2(operator bool) имеет const. Это сообщение отредактировал(а) vinter - 18.11.2013, 16:27 |
|||
|
||||
| baldina |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
да, user-defined преобразование лишь одно
а дальше все подходящие преобразования ранжируются, и выбирается лучшее. "на одно преобразование больше" это скорее фольклор, а не стандарт, хотя фольклор "правильный", т.к. длина преобразования неявно влияет на приоритет преобразования. Учитывая, что преобразование лишь одно, разная длина может означать только наличие преобразования квалификаторов (такое преобразование (surprise!) тоже является стандартным). Для квалификаторов кстати есть таблица
хотя наш случай в п. 13.3.3.2 указан явно, и даже имеется пример
ЗЫ. Кажется сам стал лучше понимать, откуда дети берутся что взялось |
||||||
|
|||||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |