2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2  След.
 
 Перегрузка в С++ в зависимости от типа
Сообщение27.08.2018, 12:26 


06/04/18
228
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include <iostream>
using namespace std;

int func(int i);
int func(bool b);

int main(){
    cout << func(0);
}
 
int func(int i){
    return 1;
}

int func(bool b){
    return b;
}
Результат работы — на вывод подается единица. Почему программа распознает константный ноль как целый ноль, а не как ложное булево значение?

 Профиль  
                  
 
 Re: Перегрузка в С++ в зависимости от типа
Сообщение27.08.2018, 13:23 
Заслуженный участник
Аватара пользователя


30/01/06
68765
Используйте false.

 Профиль  
                  
 
 Re: Перегрузка в С++ в зависимости от типа
Сообщение27.08.2018, 14:51 
Заслуженный участник


28/04/09
1880
По стандарту целочисленный литерал 0 имеет тип int.

 Профиль  
                  
 
 Re: Перегрузка в С++ в зависимости от типа
Сообщение27.08.2018, 14:52 


11/12/14
879
Qlin в сообщении #1334820 писал(а):
Почему программа распознает константный ноль как целый ноль, а не как ложное булево значение?

А почему программа должна целое число воспринимать не как целое число?
В С++ бывает много неочевидных моментов, но тут же всё правильно как раз.

 Профиль  
                  
 
 Re: Перегрузка в С++ в зависимости от типа
Сообщение27.08.2018, 15:12 
Аватара пользователя


14/12/17
723
деревня Инет-Кельманде
--- убрал, потому что любой совет будет хуже главы про перегрузку и про приведение типов в книге по С++

 Профиль  
                  
 
 Re: Перегрузка в С++ в зависимости от типа
Сообщение27.08.2018, 15:13 


06/04/18
228
EtCetera в сообщении #1334830 писал(а):
По стандарту целочисленный литерал 0 имеет тип int
.
А где найти информацию по всем арифметическим литералам?

-- 27.08.2018, 12:17 --

aa_dav в сообщении #1334831 писал(а):
А почему программа должна целое число воспринимать не как целое число?
В математике символом $0$ может быть обозначен нулевой элемент любой числовой (или даже алгебраической) системы, а также ложное булево значение.

 Профиль  
                  
 
 Re: Перегрузка в С++ в зависимости от типа
Сообщение27.08.2018, 15:21 
Аватара пользователя


14/12/17
723
деревня Инет-Кельманде
Qlin в сообщении #1334833 писал(а):
В математике символом $0$ может быть обозначен нулевой элемент любой числовой (или даже алгебраической) системы, а также ложное булево значение

А в С++ $x = x+1$ истина, если $x \neq -1$. Т.е. С++ и математическая нотация - это разные языки.

 Профиль  
                  
 
 Re: Перегрузка в С++ в зависимости от типа
Сообщение27.08.2018, 18:38 


30/01/17
208
Qlin в сообщении #1334820 писал(а):
Результат работы — на вывод подается единица. Почему программа распознает константный ноль как целый ноль, а не как ложное булево значение?

Этот вопрос можно отнести к тем, ответы на которые нужно знать как таблицу умножения, чтобы программировать на С++. Ответ на такой вопрос легко узнать и понять, но вопросов таких много, ответ нужно знать на все. Для этого достаточно прочесть книгу по теме. Что и рекомендую Вам сделать.
Вот еще один мотивирующий пример: результат работы следующей программы - "int"
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include <iostream>
using namespace std;

void func(int i);
void func(char c);

int main(){
  char a(2), b(3);
  func(a+b);
}
 
void func(int i){
  std::cout << "int" << std::endl;
}

void func(char c){
  std::cout << "char" << std::endl;
}
 


Первая книга - Страуструп(базовый уровень)
Затем - книги Саттера, Александреску, Маерса(тут собраны "подводные камни")

 Профиль  
                  
 
 Re: Перегрузка в С++ в зависимости от типа
Сообщение27.08.2018, 21:40 
Заслуженный участник
Аватара пользователя


27/04/09
24457
Уфа
Qlin в сообщении #1334833 писал(а):
А где найти информацию по всем арифметическим литералам?
А почему бы не в стандарте языка?

Qlin в сообщении #1334833 писал(а):
В математике символом $0$ может быть обозначен нулевой элемент любой числовой (или даже алгебраической) системы, а также ложное булево значение.
Языки программирования отличаются от языков общения (включая математические жаргоны таких естественных языков как русский или английский, которые объединённо называются «языком математики»), так что странно ожидать какой-то похожести a priori. Плюс у создателей конкретно C++ (и у создателей C, который сильно на него повлиял) не было цели сделать его таковым.

Можно представить язык, который считает константу 0 имеющей некоторый полиморфный тип, но даже те языки, которые так делают, обычно не доходят до полного смешения. Например, в хаскеле 0 имеет тип Num a => a, условно говоря самый общий из числовых. Хотя там же можно использовать для абстракции константу mempty :: Monoid a => a, нейтральный элемент произвольного моноида. Правда, Bool всё равно не моноид: можно воспринимать этот тип как моноид двумя достаточно одинаково хорошими способами, для которых есть типы-обёртки All и Any.

Можно было бы говорить не о моноиде, а о кольце (и это естественнее в случае целочисленных литералов типа 0), но конкретно в хаскеле нет стандартного класса для колец. Хотя наверняка где-нибудь соответствующие определения сделаны, и, возможно, с ними можно будет получить (0 :: Bool) == False, однако в этом обычно может появиться необходимость только в достаточно абстрактной ситуации, а толку писать 0 вместо False везде подряд нет, потому что разделение предотвращает больше ошибок, чем смешивание*.

* Эта часть выделена два раза и специально.

 Профиль  
                  
 
 Re: Перегрузка в С++ в зависимости от типа
Сообщение28.08.2018, 02:57 


06/04/18
228

(Оффтоп)

Ivan_B в сообщении #1334867 писал(а):
Вот еще один мотивирующий пример: результат работы следующей программы - "int"
Думаю, при сложении происходит преобразование типов char в int: складываются соответствующие ASCII-номера символов.

 Профиль  
                  
 
 Re: Перегрузка в С++ в зависимости от типа
Сообщение28.08.2018, 03:16 
Заслуженный участник
Аватара пользователя


27/04/09
24457
Уфа

(Оффтоп)

ASCII-коды как раз ни при чём, char это однобайтовый целочисленный тип (и переменные в том коде инициализируются обычными числами, не кодами символов). К тому же, кстати, отрицательным числам (раз мы говорим о char = signed char; в случае unsigned char это числа 128…255) ASCII никаких символов не сопоставляет.

 Профиль  
                  
 
 Re: Перегрузка в С++ в зависимости от типа
Сообщение28.08.2018, 07:57 


11/12/14
879

(Оффтоп)

Одну из подлинных трагедий С++ (ласково именуемого "крестоплюсы" или "кресты" для краткости) можно увидеть как раз в чарах.
Когда Керниган и Ричи придумывали язык B (предшественник C) они работали в эпоху когда у машины был как правило один тип данных - слово. Оно было и адресом и минимальной ячейкой памяти и хранилищем для целых и для инструкций (с некоторыми вариациями). Поэтому в B было по сути один примитивный тип данных - слово. И чем оно было - символом, указателем или числом выводилось из контекста (нередко символы паковали парами или даже тройками в слова для экономии.
Так вот когда K&R перешли на новую модную мини-машину PDP-11 (которую с пьедестала низведут в дальнейшем уже микроЭВМ) они столкнулись с байтом. Там уже память была весьма классической в 8/16-битную эпоху конфигурации - 65536 байт. Вот здесь им пришлось усовершенствовать B добавив в него байт и как следствие продуманную систему типов с явно обозначенными указателями и т.п - получился Си.
Не знаю почему, но в этот момент им видимо показалось, что байт главным образом нужен будет для хранения символов и они закрепили в системе типов его как char и отдельного типа для байта как числа в общем то не было - ведь и с символом можно было обращаться как с числом.
И тут были заранее разложены вот какие грабли - во первых - char стал ассоциироваться с байтом (на самом деле даже не в самом Си, а скорее уже в С++, но неважно), а для байта типа создано не было, а во вторых - для совместимости специально было неопределено есть у char знак или нет если работать с ним как с числом. И не было при этом типов signed char / unsigned char - компиляторы Си времен K&R отваливаются с ошибкой если встретят такую запись - signed/unsigned мог быть только int (и поэтому его можно было смело опускать везде где только можно, даже у типа функции).
И вот появляется C++ намереваясь сохранить обратную совместимость с C и что мы имеем:
а) все три типа: char, signed char, unsigned char являются разными (никто не является синонимом другого ни при каких обстоятельствах)
б) все эти три разных типа и все остальные десятки целочисленных типов С/С++ оказываются неспособны вывести байт как число в стандартный поток ввода-вывода std:: обязательно придётся явно привести к int, ибо нефиг.
в) то есть целочисленного байта в языке так и не появилось

Изображение

 Профиль  
                  
 
 Re: Перегрузка в С++ в зависимости от типа
Сообщение28.08.2018, 09:36 


11/12/14
879
P.S.

(Оффтоп)

в дополнение к предыдущему:
Используется синтаксис C++
    #include <cstdint>
    #include <iostream>
    using namespace std;
     
    int main &#40;&#41; {
      uint8_t x = 67;
      std::cout << "x=" << x << "\n";
      return 0;
    }
 

Догадайтесь каков будет результат работы программы...

 Профиль  
                  
 
 Re: Перегрузка в С++ в зависимости от типа
Сообщение28.08.2018, 11:26 


30/01/17
208
arseniiv в сообщении #1334915 писал(а):
А почему бы не в стандарте языка?

- Вопрос непосредственно следует за ссылкой на нужное место в стандарте. Значит стандарт не помог.
- Стандарт это справочник. Чтобы пользоваться справочником, нужно хотя бы знать что искать. "Арифметические литералы" - нет такого термина.
- Учиться лучше по учебнику.
- Стандарт сухо описывает язык. Он не дает ответов на вопрос зачем оно так сделано и как этим нужно пользоваться. Вот и получается потом, что топором гвозди забивают.
Мне сложно себе представить зачем могло понадобится, чтобы $0$ был типа bool.

Qlin в сообщении #1334983 писал(а):
при сложении происходит преобразование типов char в int

То что Вы это знали и без моего примера очень хорошо, но я все равно рекомендую системный подход. Он даст возможность легко отвечать на подобные вопросы самостоятельно.
Если ответ на исходный вопрос Вы знали, но Вас интересовало почему оно так(с философской точки зрения), то не совсем понятно как Вы бы хотели, чтобы оно было сделано. Кроме того, обсуждение подобных вопросов требует более высокой квалификации чем С++ программист.

 Профиль  
                  
 
 Re: Перегрузка в С++ в зависимости от типа
Сообщение28.08.2018, 11:29 
Заслуженный участник


28/04/09
1880

(К вопросу о signedness типа char)

arseniiv в сообщении #1334985 писал(а):
char = signed char
Это не так:
Стандарт языка C++ в 1-м абзаце раздела Fundamental types [basic.fundamental] писал(а):
Plain char, signed char, and unsigned char are three distinct types... In any particular implementation, a plain char object can take on either the same values as a signed char or an unsigned char; which one is implementation-defined.

(К вопросу о целочисленном байте)

aa_dav в сообщении #1334994 писал(а):
то есть целочисленного байта в языке так и не появилось
Начиная с C++17, в C++ появился std::byte. Правда, по несколько загадочным причинам для него не предусмотрели никакой стандартный вывод в стандартный поток, поэтому Ваш пример с ним просто не скомпилируется (что, в определенной степени, можно считать даже плюсом; особенно если не обращать внимания на доступность для восприятия сообщений об ошибках), для вывода же необходимо явное приведение std::byte к целочисленному типу (например, с помощью функции std::to_integer). В общем, хотели как лучше, а получилось C++. :-)

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 23 ]  На страницу 1, 2  След.

Модераторы: Karan, PAV, Toucan, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group