Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> перегрузка функций и приведение типов 
:(
    Опции темы
GrafF812
Дата 31.8.2010, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 205
Регистрация: 3.12.2009

Репутация: нет
Всего: нет



Привет, есть такой вызов функции square()
Код


 // int square(int x) {return x * x;}
double square(double y) {return y * y;}

int main()
{
    setlocale(LC_CTYPE, "Russian_Russia.1251");
    
    cout << "Квадрат целого числа 7 равен "
        << square(7) << endl
        << "Квадрат числа 7.5 типа double равен "
        <<square(7.5) << endl;
    
    return 0;
}

Подскажите почему при вызове функции square(7), вызывается версия square(double) а не генерируется сообщение об ошибки?
PM MAIL   Вверх
djamshud
Дата 31.8.2010, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 4
Всего: 39



Потому что int преобразуется в double.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
GrafF812
Дата 31.8.2010, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 205
Регистрация: 3.12.2009

Репутация: нет
Всего: нет



djamshud, в чем тогда смысл перегрузки функций ?, если все равно происходит неявное преобразование типов, как в этом случае.
PM MAIL   Вверх
djamshud
Дата 31.8.2010, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 4
Всего: 39



В том, чтобы можно было сделать так:

Код

struct point{
double x,y;};

void foo(double x,double y){
...
}

void foo(struct point const &point){
...
}


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

Добавлено через 5 минут и 42 секунды
ну или вот пример из моей недавней практики:

Код

void foo(char const *str){
...
}

void foo(void const *ptr){
...
}


Одна логика для работы со строкой и совершенно другая - для любых других указателей.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
ИванМ
Дата 31.8.2010, 15:52 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 3
Всего: 23



Цитата(GrafF812 @  31.8.2010,  11:35 Найти цитируемый пост)
в чем тогда смысл перегрузки функций

В вашем коде никакой перегрузки функций и нет. Если раскомментировать первую строчку, то как раз перегрузка произойдет. Неявное преобразование типа происходит, только если нет перегрузки.
PM MAIL   Вверх
mes
Дата 31.8.2010, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(ИванМ @  31.8.2010,  14:52 Найти цитируемый пост)
 Неявное преобразование типа происходит, только если нет перегрузки.

звучит резковато  smile  


Это сообщение отредактировал(а) mes - 31.8.2010, 18:15


--------------------
PM MAIL WWW   Вверх
ИванМ
Дата 31.8.2010, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 3
Всего: 23



mes, я вообще очень суров smile 
PM MAIL   Вверх
Леопольд
Дата 31.8.2010, 20:45 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 3
Всего: 13



Цитата(ИванМ @  31.8.2010,  15:52 Найти цитируемый пост)
Неявное преобразование типа
Здесь имеет место так называемое продвижение. int неявно преобразуется к double, но не наоборот.
Когда вызывается функция, происходит поиск её имени. Здесь нет ползовательских (user-defined) типов (проще говоря, классов или енумов), поэтому ADL не выполняется. Выбирается та функция, которая подходит лучше всего, т.е. та, для вызова которой надо сделать как можно меншьше допустимых приведений. 

Если в этой цепочке присутствуют приведения типа определённые пользователем, (не explicit конструкторы классов или всевозможные operator T()), то допускается не более одного.
Код
#include <iostream>

struct One{
};

struct Two{
   Two() {}
   Two(One) {}
   operator double() { return 0; }
};

void foo(double){
   std::cout<<"foo"<<std::endl;
}

int main(){
   One one;
   Two two;

   //foo(one); // error: cannot convert 'One' to 'double' for argument '1' to 'void foo(double)'
   foo(static_cast<Two>(one)); // делаем каст вручную
   foo(two);
   return 0;
}
codepad.org


Это сообщение отредактировал(а) Леопольд - 31.8.2010, 20:51


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
ИванМ
Дата 31.8.2010, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 3
Всего: 23



Цитата(Леопольд @  31.8.2010,  20:45 Найти цитируемый пост)
int неявно преобразуется к double, но не наоборот.

Вот в этом месте не понятно. Вы имеете ввиду конкретный случай или вообще.
PM MAIL   Вверх
Леопольд
Дата 31.8.2010, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 3
Всего: 13



codepad.org
Код
#include <iostream>

struct One{
};

struct Two{
   Two() {}
   Two(One) {}
   operator double() { return 0; }
};

void foo(double){
   std::cout<<"foo(double)"<<std::endl;
}

void bar();

int main(){
   One one;
   Two two;

   //foo(one); // error: cannot convert 'One' to 'double' for argument '1' to 'void foo(double)'
   foo(static_cast<Two>(one));
   foo(two);

   bar();

   return 0;
}

void foo(Two){
   std::cout<<"foo(Two)"<<std::endl;
}

void bar(){
   One one;
   Two two;
   foo(one);
   foo(two);
}


Добавлено @ 20:59
Цитата(ИванМ @  31.8.2010,  20:57 Найти цитируемый пост)
Вы имеете ввиду конкретный случай или вообще. 
Здесь речь про "продвижение" встроенных типов, оно идёт в одном напрвалении: char -> short -> int -> long -> float -> double . Здесь я "опустил" unsigned типы.


Это сообщение отредактировал(а) Леопольд - 31.8.2010, 21:03


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
mes
Дата 1.9.2010, 00:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Леопольд @  31.8.2010,  19:57 Найти цитируемый пост)
оно идёт в одном напрвалении: char -> short -> int -> long -> float -> double 

все в одну бочку ?!  smile 


--------------------
PM MAIL WWW   Вверх
Леопольд
Дата 1.9.2010, 08:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 3
Всего: 13



Цитата(mes @  1.9.2010,  00:13 Найти цитируемый пост)
все в одну бочку ?!
Я точно уже не помню. Лазить выскивать точную инфу нет времени...


Это сообщение отредактировал(а) Леопольд - 1.9.2010, 08:58


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
baldina
Дата 1.9.2010, 09:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



в С++ компилятор осуществляет неявное (implicit) преобразование типов во время разбора выражений. эта некоторая слабость типизации есть дань совместимости с С и для опытных программистов довольно удобна, хотя иногда приводит к трудноуловимым ошибкам.
Правила преобразования (почти всегда) интуитивно понятны, хотя и не настолько просты, что бы выразить их одной строчкой.
Для избежания неявного преобразования есть два механизма - явное приведение типов _cast, (type), type() и ключевое слово explicit, применимое, к сожалению, лишь в конструкторах. Замечу, что первое - явное преобразование - не защищает от неявного:
Код

void foo (double);
foo ((int)5.5); // 5.5 -> int - > double -> 5.0

используя перегрузку функций можно специализировать функцию для определенного типа http://codepad.org/jJ7DkWBy, компилятор будет применять функцию, наиболее близкую по типу параметров, однако неявное преобразование это не отменяет
PM MAIL   Вверх
ИванМ
Дата 1.9.2010, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 3
Всего: 23



Леопольд, а как называется неявное преобразование double к int?
PM MAIL   Вверх
mes
Дата 1.9.2010, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Леопольд @  1.9.2010,  07:43 Найти цитируемый пост)
Я точно уже не помню. 

тогда поправлю: 
Цитата(Леопольд @  31.8.2010,  19:45 Найти цитируемый пост)
Здесь имеет место так называемое продвижение. int неявно преобразуется к double, но не наоборот.

тут нет никакого продвижения smile

Цитата(ИванМ @  1.9.2010,  12:29 Найти цитируемый пост)
как называется неявное преобразование double к int? 

Floating-integral conversions

Цитата

4.9 Floating-integral conversions 
1 An rvalue of a floating point type can be converted to an rvalue of an integer type. The conversion truncates;
that is, the fractional part is discarded. The behavior is undefined if the truncated value cannot be
represented in the destination type. [Note: If the destination type is bool, see 4.12. ]
2 An rvalue of an integer type or of an enumeration type can be converted to an rvalue of a floating point
type. The result is exact if possible. Otherwise, it is an implementation-defined choice of either the next
lower or higher representable value. [Note: loss of precision occurs if the integral value cannot be represented
exactly as a value of the floating type. ] If the source type is bool, the value false is converted to
zero and the value true is converted to one.



--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0583 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.