Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Tulosba
:)
Эксперт С++
4396 / 3232 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
#1

Приоритет преобразований внутри if - C++

22.07.2013, 11:18. Просмотров 748. Ответов 15
Метки нет (Все метки)

Всем привет.

Рассмотрим такой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
 
class C {
    typedef void (C::*fp)() const;
public:
    operator fp() const 
    { 
        std::cout << "fp conversion\n";
        return 0; 
    }
    operator bool() const 
    { 
        std::cout << "bool conversion\n";
        return false; 
    }
    operator int() const 
    { 
        std::cout << "int conversion\n"; 
        return 0; 
    }
};
 
int main()
{
    C c;
    if( c )  { /* do smth */  }
}
В данном случае вывод будет такой:
bool conversion
Если убрать operator bool, то такой:
int conversion
И если теперь убрать и operator int, то такой:
fp conversion
Отсюда вопрос: какой приоритет вызова преобразований в условной конструкции if, каким пунктом стандарта это регламентируется?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.07.2013, 11:18
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Приоритет преобразований внутри if (C++):

Неоднозначность преобразований. Как задать "приоритет" преобразований - C++
В моем классе есть три функции преобразования (int, double, char), и все они мне нужны. Но мне нужно, чтобы когда я явно не указываю, во...

Точности вычислений и преобразований double - C++
Всем привет! Вопрос точности вычислений и преобразований double. Объясните пожалуйста следующее: Арифметические операции: ...

Реализация простеньких методов преобразований - C++
есть ли материалы (или готовая программа) 4тобы реализовать простенький метод преобразований ( например фурье) на vc ++ ?

Написать программу преобразований массива - C++
Дан массив c0, c1, c2,…, c2m-1. Написать программу преобразования массива в массив с элементами, соответственно равными: c2m-1, c2m-2,…,...

Реализации преобразований с геометрической фигурой (сферой) - C++
Товарищи подскажите кто чем сможет. Надо написать программу, позволяющую делать различные преобразования со сферой (перемещение, сжатие,...

Работа с указателями(небольшой вопрос насчет преобразований) - C++
*((uint*)space)=SIGNATURE; space+=sizeof(uint); Как записать в одну строчку ? *(((uint*)space)++)=SIGNATURE; так не...

15
0x10
2478 / 1651 / 247
Регистрация: 24.11.2012
Сообщений: 4,087
22.07.2013, 11:22 #2
Ох, как бы так вспомнить чтобы не соврать...
Для операторов вроде два этапа:сначала пользовательские преобразования, потом стандартные. Т.е. пока есть bool, объект сразу приводится к нему. Если нет bool, но есть int, то сначала выполняется приведение к int, а уже int можно привести к bool.
0
Tulosba
:)
Эксперт С++
4396 / 3232 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
22.07.2013, 11:35  [ТС] #3
Цитата Сообщение от 0x10 Посмотреть сообщение
Если нет bool, но есть int, то сначала выполняется приведение к int, а уже int можно привести к bool.
Ну, это мы видим из результатов выполнения. Просто хотелось бы не быть голословным. Вот есть пункт стандарта например:
4.12 Boolean conversions
A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool.
A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true.
A prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false.
Но про приоритет тут ни слова. Вероятно нужен другой пункт. Но какой?
0
0x10
2478 / 1651 / 247
Регистрация: 24.11.2012
Сообщений: 4,087
22.07.2013, 12:02 #4
Последний абзац: http://en.cppreference.com/w/cpp/language/implicit_cast
Где конкретно искать в стандарте - не подскажу.

Добавлено через 2 минуты
Видимо 13.3.3.1 Implicit conversion sequences
1
castaway
Эксперт С++
4887 / 3022 / 370
Регистрация: 10.11.2010
Сообщений: 11,080
Записей в блоге: 10
Завершенные тесты: 1
22.07.2013, 12:05 #5
Chapter 4 Standard conversions
0
Tulosba
:)
Эксперт С++
4396 / 3232 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
22.07.2013, 18:18  [ТС] #6
Цитата Сообщение от 0x10 Посмотреть сообщение
http://en.cppreference.com/w/cpp/language/implicit_cast
Кстати, интересный момент по ссылке.
Implicit conversion sequence consists of the following, in this order:
1) zero or one standard conversion sequence
2) zero or one user-defined conversion
3) zero or one standard conversion sequence
Думал сначала, что опечатка, т.к. пп. 1 и 3 одинаковые. Оказалось, что нет. Например для случая когда отсутствует operator bool получаем: 0 - 1(C->int) - 1(int->bool).

А еще меня смутил пункт:
Qualification conversions
A prvalue of type pointer to member of cv-qualified type T in class X can be converted to prvalue pointer to member of more cv-qualified type T in class X.
Это о каких преобразованиях речь? Если что-то типа этого:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
 
class C
{
public:
    void f() { std::cout << "f()\n"; }
    void g() const { std::cout << "g()\n"; }
    typedef void (C::*fp)();
};
 
int main() {
    
    C::fp pointer = &C::f;
    
    C c;
    
    (c.*pointer)();
    
    pointer = &C::g; // Не работает
    
    (c.*pointer)();
    
    return 0;
}
, то не работает. https://ideone.com/p0Ym87.
0
Croessmah
Ушел
Эксперт CЭксперт С++
13553 / 7704 / 872
Регистрация: 27.09.2012
Сообщений: 19,006
Записей в блоге: 3
Завершенные тесты: 1
22.07.2013, 18:31 #7
Я бы еще добавил в класс такой оператор:
C++
1
2
3
4
     operator void*(){
        std::cout << "void* conversion\n"; 
        return 0; 
     }
0
Tulosba
:)
Эксперт С++
4396 / 3232 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
22.07.2013, 18:40  [ТС] #8
Croessmah, кстати, не понятно почему в if'е предпочтение отдается operator void*, а не operator bool.
0
0x10
2478 / 1651 / 247
Регистрация: 24.11.2012
Сообщений: 4,087
22.07.2013, 18:42 #9
Tulosba, по ссылке как раз описано.
Указатель может быть приведен к булу. И это нормально, на этом преобразование заканчивается.
А если есть приведение к булу, то объект далее может быть приведен к инту. Поэтому возможен всякий бред в духе int n = std::cin.
1
Tulosba
:)
Эксперт С++
4396 / 3232 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
22.07.2013, 18:52  [ТС] #10
Цитата Сообщение от 0x10 Посмотреть сообщение
Указатель может быть приведен к булу. И это нормально, на этом преобразование заканчивается.
Так ведь "родной" тип для условного выражения внутри if'а - bool. Из этого исхожу.
P.S. Кстати, если сделать explicit operator void* (С++11), то вызываться будет уже operator bool.
0
0x10
2478 / 1651 / 247
Регистрация: 24.11.2012
Сообщений: 4,087
22.07.2013, 19:07 #11
Tulosba, забудем пока про С++11.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class A
{
public:
    operator bool() const { return true; }
};
 
class B
{
public:
    operator void*() { return NULL; }
};
 
int main()
{
    A obj;
    // Вызывается сразу пользовательский operator bool
    if (obj) { }
 
    // вызывается operator bool,
    // а затем стандартное преобразование bool -> int
    // Кажется, мы не этого хотели.
    int n = obj;
 
    B obj2;
 
    // Вызывается operator void*, затем стандартное преобразование void* -> bool
    if (obj2) { }
 
    // а вот такой ереси уже сделать нельзя, т.к. указатель неявно не приводится к int.
    //int m = obj2;
 
    return 0;
}
0
Tulosba
:)
Эксперт С++
4396 / 3232 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
23.07.2013, 13:05  [ТС] #12
Цитата Сообщение от 0x10 Посмотреть сообщение
// Вызывается operator void*, затем стандартное преобразование void* -> bool
Это потому что других пользовательских преобразований нет.
Предлагаю посмотреть на такой код и поубирать операторы преобразования по очереди:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
 
class B
{
public:
    operator bool() { std::cout << "B::bool\n"; return true; } // 1
    operator void*() { std::cout << "B::void*\n"; return NULL; } // 2
    operator bool() const { std::cout << "B::bool const\n"; return true; } // 3
    operator void*() const { std::cout << "B::void* const\n"; return NULL; } // 4     
};
 
int main()
{
    B obj2;
 
    // Вызывается operator bool, если нет, то operator void*, если нет, то operator bool const, если нет, то operator void* const
    if (obj2) { }
 
    return 0;
}
Собственно, в этом случае как раз видно, что преобразование к bool приоритетнее (при одинаковый cv-квалификаторах), чем преобразование к void*

Добавлено через 15 часов 26 минут
Цитата Сообщение от 0x10 Посмотреть сообщение
Поэтому возможен всякий бред в духе int n = std::cin.
Где возможен?
0
0x10
2478 / 1651 / 247
Регистрация: 24.11.2012
Сообщений: 4,087
23.07.2013, 13:11 #13
Цитата Сообщение от Tulosba Посмотреть сообщение
Где возможен?
Был бы возможен, будь у класса оператор приведения к bool.
0
Croessmah
Ушел
Эксперт CЭксперт С++
13553 / 7704 / 872
Регистрация: 27.09.2012
Сообщений: 19,006
Записей в блоге: 3
Завершенные тесты: 1
23.07.2013, 13:23 #14
Цитата Сообщение от 0x10 Посмотреть сообщение
Был бы возможен, будь у класса оператор приведения к bool.
explicit
0
0x10
2478 / 1651 / 247
Регистрация: 24.11.2012
Сообщений: 4,087
23.07.2013, 13:31 #15
Цитата Сообщение от Croessmah Посмотреть сообщение
explicit
Знаю. Чуть выше сказал, что пока забываем про 11 стандарт - по крайней мере, тогда становится понятно зачем писать оператор void*.
0
23.07.2013, 13:31
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.07.2013, 13:31
Привет! Вот еще темы с ответами:

OpenCV определить координаты точки по матрице преобразований - C++
Проблема в следующем: есть картинка полученная с камеры, точнее видеопоток по отдельным картинкам. На картинке определенная область...

приоритет операций - C++
while(*a++==*b++ &amp;&amp; *a!=NULL) хочу сравнить до конца строки &quot;а&quot;. почему не работает? где-то дело в приоритете, а где найти не...

Приоритет операторов - C++
int x = 4; int y = 5; cout &lt;&lt; (x == y ? ++x, ++y : --x, --y); Оператор запятая здесь не выполняется из-за приоритета? ...

приоритет потоков - C++
Где можно найти информацию по таким темам: Относительный приоритет потока, динамическое изминение уровня потока?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru