И если Вы не считаете полиморфизм в C++ синтаксическим сахаром, то приведите пример алгоритма, который не реализуем без использования полиморфизма другими средствами языка.
Вопросы по С/С++ (СИ)
VladislavS, Вы пропустили мой классический пример кривизны ad-hoc полиморфизма? Повторить?
И если Вы не считаете полиморфизм в C++ синтаксическим сахаром, то приведите пример алгоритма, который не реализуем без использования полиморфизма другими средствами языка.
И если Вы не считаете полиморфизм в C++ синтаксическим сахаром, то приведите пример алгоритма, который не реализуем без использования полиморфизма другими средствами языка.
Последний раз редактировалось ПростоНуб Вс сен 29, 2019 12:06:55, всего редактировалось 1 раз.
- Реклама
неужели все достоинства С++ сводятся к легкой возможности реализации глупых фантазий?!
имхо, это не хорошо. до этого существовал естественный ограничитель безумства - дикая сложность реализации. теперь это барьер снят. и?
имхо, это не сделает мир программирования лучше.
имхо, это не хорошо. до этого существовал естественный ограничитель безумства - дикая сложность реализации. теперь это барьер снят. и?
имхо, это не сделает мир программирования лучше.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3709280#p3709280"]VladislavS, Вы пропустили мой классический пример кривизны ad-hoc полиморфизма? Повторить?[/uquote]С дуру и хрен сломать можно.
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3709280#p3709280"]И если Вы не считаете полиморфизм в C++ синтаксическим сахаром, то приведите пример алгоритма, который не реализуем без использования полиморфизма другими средствами языка.[/uquote]Списки типов.
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3709280#p3709280"]И если Вы не считаете полиморфизм в C++ синтаксическим сахаром, то приведите пример алгоритма, который не реализуем без использования полиморфизма другими средствами языка.[/uquote]Списки типов.
VladislavS, при чем тут списки типов? Это алгоритм?
Вы вообще знаете, что такое синтаксический сахар?
Так вот и приведите пример алгоритма, которые не реализуем на C++ без использования полиморфизма.
Добавлено after 11 minutes 22 seconds:
VladislavS, с дуру можно все. Но когда конструкция языка повышает вероятность возникновения этого "с дуру", ее и называют спорной. Так снижение трудозатрат на написание кода, легко может перекрыться повышением трудозатрат при отладке и сопровождении кода. И я сам на это многократно нарывался.
Если Вы действительно считаете даже классический пример полиморфизма в С++ "дуростью", то что же можно сказать о боле сложных его применениях )))
Вы вообще знаете, что такое синтаксический сахар?
Так вот и приведите пример алгоритма, которые не реализуем на C++ без использования полиморфизма.
Добавлено after 11 minutes 22 seconds:
VladislavS, с дуру можно все. Но когда конструкция языка повышает вероятность возникновения этого "с дуру", ее и называют спорной. Так снижение трудозатрат на написание кода, легко может перекрыться повышением трудозатрат при отладке и сопровождении кода. И я сам на это многократно нарывался.
Если Вы действительно считаете даже классический пример полиморфизма в С++ "дуростью", то что же можно сказать о боле сложных его применениях )))
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3709313#p3709313"]VladislavS, при чем тут списки типов? Это алгоритм?
Вы вообще знаете, что такое синтаксический сахар?
Так вот и приведите пример алгоритма, которые не реализуем на C++ без использования полиморфизма.[/uquote]Я, пожалуй, отвечу на все три вопроса одним кусочком кода. В нём и списки типов, и сложные алгоритмы, и полиморфизм, и синтаксический сахар. Инициализация всех ног контроллера разом.
[uquote="ARV",url="/forum/viewtopic.php?p=3709286#p3709286"]имхо, это не сделает мир программирования лучше.[/uquote]Уже сделало, а будет ещё лучше.
Приложу ещё один кусочек кода. Класс, поддерживающий все микросхемы eeprom 24Сxx. Да, его было можно сделать и без шаблонов, и без constexpr, и без перегрузок функций. Но я как представлю это безудержный поток #ifdef-ов...
Вы вообще знаете, что такое синтаксический сахар?
Так вот и приведите пример алгоритма, которые не реализуем на C++ без использования полиморфизма.[/uquote]Я, пожалуй, отвечу на все три вопроса одним кусочком кода. В нём и списки типов, и сложные алгоритмы, и полиморфизм, и синтаксический сахар. Инициализация всех ног контроллера разом.
Код: Выделить всё
ConfigList
< PinMode::PushPull_MediumSpeed<0>,
PA_3, PA_5, PA_7, PA_12,
GpioB<0x3F>, PB_13, PB_14, PB_15,
GpioC<0xF>, PC_5, PC_6, PC_8, PC_9, PC_15,
PinMode::Floating,
PA_0, PA_1, PA_2, PA_4, PA_6, PA_10, PA_11,
PB_6, PB_12, PC_4, PC_7,
PinMode::PullDown,
PA_13, PA_14,
PinMode::AF_PushPull_MediumSpeed,
PA_8, PA_9, PA_15,
PinMode::AF_OpenDrain_MediumSpeed,
PB_8, PB_9, PB_10, PB_11,
PinMode::AF_PushPull_HighSpeed,
PB_7,
PinMode::Floating,
CfgCmd::AllUnusedPins
>::mode();Приложу ещё один кусочек кода. Класс, поддерживающий все микросхемы eeprom 24Сxx. Да, его было можно сделать и без шаблонов, и без constexpr, и без перегрузок функций. Но я как представлю это безудержный поток #ifdef-ов...
Спойлер
Код: Выделить всё
#pragma once
namespace EEPROM_AT24C
{
enum class EEType { AT24C01=0, AT24C02=1, AT24C04=2, AT24C08=3, AT24C16=4,
AT24C32=5, AT24C64=6, AT24C128=7, AT24C256=8, AT24C512=9, AT24CM01=10, AT24CM02=11 };
struct EEParams
{
uint32_t size;
uint32_t page_size;
};
static constexpr EEParams AllParams[12] = //Объём памяти и размер страницы для всех чипов 24Cxx
{ {128,8}, {256,8}, {512,16}, {1024*1,16}, {1024*2,16},
{1024*4,38}, {1024*8,32}, {1024*16,64}, {1024*32,64}, {1024*65,128}, {1024*128,256}, {1024*256,256} };
template<typename TI2C, typename TDelay, EEType eeType, uint8_t HW_ADR>
class EE_24C
{
public:
_inline_ constexpr EE_24C(){};
static _inline_ bool ReadByte(uint16_t adr, uint8_t *data)
{
if constexpr (uint32_t(eeType)>=uint32_t(EEType::AT24CM01))
{ //Микросхемы с двухбайтовой адресацией + биты в HW_ADR
uint8_t new_adr = hw_adr + (((adr>>16)&0x3)<<1);
return TI2C::ReadReg(new_adr,(uint16_t)adr, data, (uint8_t)1);
}
else if constexpr (uint32_t(eeType)>=uint32_t(EEType::AT24C32))
{ //Микросхемы с двухбайтовой адресацией
return TI2C::ReadReg(hw_adr,(uint16_t)adr, data, (uint8_t)1);
}
else if constexpr(uint32_t(eeType)<=uint32_t(EEType::AT24C02))
{ //Микросхемы с однобайтовой адресацией
return TI2C::ReadReg(hw_adr,(uint8_t)adr, data, (uint8_t)1);
}
else
{ //Микросхемы с адресацией 1 байт + биты в HW_ADR
uint8_t new_adr = hw_adr + (((adr>>8)&0x3)<<1);
return TI2C::ReadReg(new_adr,(uint8_t)adr, data, (uint32_t)1);
}
}
static _inline_ bool WriteByte(uint16_t adr, uint8_t data)
{
if constexpr (uint32_t(eeType)>=uint32_t(EEType::AT24CM01))
{ //Микросхемы с двухбайтовой адресацией + биты в HW_ADR
uint8_t new_adr = hw_adr + (((adr>>16)&0x3)<<1);
return TI2C::WriteReg(new_adr,(uint16_t)adr, &data, (uint8_t)1);
}
else if constexpr (uint32_t(eeType)>=uint32_t(EEType::AT24C32))
{ //Микросхемы с двухбайтовой адресацией
return TI2C::WriteReg(hw_adr,(uint16_t)adr, &data, (uint8_t)1);
}
else if constexpr(uint32_t(eeType)<=uint32_t(EEType::AT24C02))
{ //Микросхемы с однобайтовой адресацией
return TI2C::WriteReg(hw_adr,(uint8_t)adr, &data, (uint8_t)1);
}
else
{ //Микросхемы с адресацией 1 байт + биты в HW_ADR
uint8_t new_adr = hw_adr + (((adr>>8)&0x3)<<1);
return TI2C::WriteReg(new_adr,(uint8_t)adr, &data, (uint8_t)1);
}
}
static _inline_ bool ReadData(uint32_t adr, uint8_t *data, uint32_t length)
{
if constexpr (uint32_t(eeType)>=uint32_t(EEType::AT24CM01))
{ //Микросхемы с двухбайтовой адресацией + биты в HW_ADR
uint8_t new_adr = hw_adr + (((adr>>16)&0x3)<<1);
return TI2C::ReadReg(new_adr,(uint16_t)adr, data, (uint32_t)length);
}
else if constexpr (uint32_t(eeType)>=uint32_t(EEType::AT24C32))
{ //Микросхемы с двухбайтовой адресацией
return TI2C::ReadReg(hw_adr, (uint16_t)adr, data, (uint32_t)length);
}
else if constexpr(uint32_t(eeType)<=uint32_t(EEType::AT24C02))
{ //Микросхемы с однобайтовой адресацией
return TI2C::ReadReg(hw_adr,(uint8_t)adr, data, (uint8_t)length);
}
else
{ //Микросхемы с адресацией 1 байт + биты в HW_ADR
uint8_t new_adr = hw_adr + (((adr>>8)&0x3)<<1);
return TI2C::ReadReg(new_adr,(uint8_t)adr, data, (uint32_t)length);
}
}
static _inline_ bool WriteData(uint32_t adr, uint8_t *data, uint32_t length)
{
if( (((uint32_t)adr) + ((uint32_t)length)) > eeparams.size) return false;
uint32_t page_shift = adr&(eeparams.page_size-1);
//Шаг 1: Запись начального кусочка
uint32_t data2write = length<(eeparams.page_size-page_shift) ? length : (eeparams.page_size-page_shift);
if(!WriteDataInOnePage(adr,data,data2write)) return false;
length -= data2write;
adr+=data2write;
data+=data2write;
//Шаг 2: Запись остальных страниц (они уже выровнены)
while(length)
{
TDelay::template Delay_ms<5>(); //Ждать пока предыдущая страница не запишется
data2write = length<eeparams.page_size ? length : eeparams.page_size;
if(!WriteDataInOnePage(adr,data,data2write)) return false;
length -= data2write;
adr+=data2write;
data+=data2write;
}
return true;
}
private:
static constexpr uint8_t hw_adr=0xA0+((HW_ADR&0x7)<<1);
static constexpr EEParams eeparams = AllParams[uint32_t(eeType)];
static _inline_ bool WriteDataInOnePage(uint32_t adr, uint8_t *data, uint32_t length)
{
if constexpr (uint32_t(eeType)>=uint32_t(EEType::AT24CM01))
{ //Микросхемы с двухбайтовой адресацией + биты в HW_ADR
uint8_t new_adr = hw_adr + (((adr>>16)&0x3)<<1);
return TI2C::WriteReg(new_adr,(uint16_t)adr, data, (uint32_t)length);
}
else if constexpr (uint32_t(eeType)>=uint32_t(EEType::AT24C32))
{ //Микросхемы с двухбайтовой адресацией
if constexpr(eeparams.page_size>255)
return TI2C::WriteReg(hw_adr,(uint16_t)adr, data, (uint32_t)length);
else
return TI2C::WriteReg(hw_adr,(uint16_t)adr, data, (uint8_t)length);
}
else if constexpr(uint32_t(eeType)<=uint32_t(EEType::AT24C02))
{ //Микросхемы с однобайтовой адресацией
return TI2C::WriteReg(hw_adr,(uint8_t)adr, data, (uint8_t)length);
}
else
{ //Микросхемы с адресацией 1 байт + биты в HW_ADR
uint8_t new_adr = hw_adr + (((adr>>8)&0x3)<<1);
return TI2C::WriteReg(new_adr,(uint8_t)adr, data, (uint8_t)length);
}
}
};
} // namespace EEPROM_AT24C
Последний раз редактировалось VladislavS Вс сен 29, 2019 13:24:48, всего редактировалось 2 раза.
- Реклама
VladislavS, Вы утверждаете что тоже самое нельзя сделать без использования полиморфизма? 
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3709330#p3709330"]VladislavS, Вы утверждаете что тоже самое нельзя сделать без использования полиморфизма?
[/uquote]Как говорил Reflector, у вас сейчас обязательно найдётся неотложное дело и мы не увидим хотя бы близкой альтернативы.
ПростоНуб, А без демагонии? Вы утвердете, что проинициализировать пины МК без использования полиморфизма на C++ невозможно?
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
Демагогией занимаетесь как раз вы, а я конкретный пример привёл. Перекрыть который, я так понимаю, не чем?
- Сообщения: 2089
- Зарегистрирован: Вс июн 19, 2016 09:32:03
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3709253#p3709253"]я же писал выше, что параметрический полиморфизм на мономорфном ядре есть лишь синтаксический сахар. Очень спорно, перевешивают ли его достоинства его недостатки.
Праметрический полиморфизм без недостатков есть, например, в ML, но его обсуждение явно выходит за рамки темы.[/uquote]
Недостатки есть везде, но если брать более современные языки родственные С, то там почти везде есть дженерики. В С++ есть шаблоны и это активно развивающееся направление языка, что явно указывает на его полезность, дженерики в разных реализациях есть в C#, Java, D, Rust, причем в части языков необходимость их добавления осознали на сразу. В Gо пока ничего такого нет и это была ошибка, насколько знаю добавление обобщенного программирования в Go уже запланированно вместе с контрактами... А если что-то забраковывать на основании имеющихся недостатков, то вообще языков программирования не останется

Праметрический полиморфизм без недостатков есть, например, в ML, но его обсуждение явно выходит за рамки темы.[/uquote]
Недостатки есть везде, но если брать более современные языки родственные С, то там почти везде есть дженерики. В С++ есть шаблоны и это активно развивающееся направление языка, что явно указывает на его полезность, дженерики в разных реализациях есть в C#, Java, D, Rust, причем в части языков необходимость их добавления осознали на сразу. В Gо пока ничего такого нет и это была ошибка, насколько знаю добавление обобщенного программирования в Go уже запланированно вместе с контрактами... А если что-то забраковывать на основании имеющихся недостатков, то вообще языков программирования не останется
Зачем мелочиться, можно из языка выкинуть почти все, главное чтобы он остался полным по Тьюрингу, и все выкинутое будет синтаксическим сахаромВы вообще знаете, что такое синтаксический сахар?
Так вот и приведите пример алгоритма, которые не реализуем на C++ без использования полиморфизма.
Последний раз редактировалось Reflector Вс сен 29, 2019 13:43:10, всего редактировалось 1 раз.
VladislavS, демагогия, это когда на прямой вопрос вместо "да" или "нет", отвечают что угодно, лишь бы на вопрос не ответить. Так да или нет?
Добавлено after 6 minutes 34 seconds:
Reflector, прошу прощения, но я называю ad-hoc полиморфизм спорным преимуществом, а не ненужным.
Почему Вы не ответили на мой прямой вопрос к Вам в классическом примере полиморфизма в C++? Так что будет сравнивать полиморфный шаблон? Указатели или то, на что они указывают? А если речь будет уже о сложных объектах, с тысячами срок кода их реализации?
Добавлено after 9 minutes 58 seconds:
[uquote="Reflector",url="/forum/viewtopic.php?p=3709342#p3709342"]можно из языка выкинуть почти все, главное чтобы он остался полным по Тьюрингу, и все выкинутое будет синтаксическим сахаром[/uquote]
Вы совершенно правы. По определению синтаксического сахара - это именно так!
Другое дело, что, например, ситаксический сахар в виде оператора for лишен недостатков, а синтаксический сахар в виде ad-hoc полиморфизма такими недостатками обладает.
Добавлено after 6 minutes 34 seconds:
Reflector, прошу прощения, но я называю ad-hoc полиморфизм спорным преимуществом, а не ненужным.
Почему Вы не ответили на мой прямой вопрос к Вам в классическом примере полиморфизма в C++? Так что будет сравнивать полиморфный шаблон? Указатели или то, на что они указывают? А если речь будет уже о сложных объектах, с тысячами срок кода их реализации?
Добавлено after 9 minutes 58 seconds:
[uquote="Reflector",url="/forum/viewtopic.php?p=3709342#p3709342"]можно из языка выкинуть почти все, главное чтобы он остался полным по Тьюрингу, и все выкинутое будет синтаксическим сахаром[/uquote]
Вы совершенно правы. По определению синтаксического сахара - это именно так!
Другое дело, что, например, ситаксический сахар в виде оператора for лишен недостатков, а синтаксический сахар в виде ad-hoc полиморфизма такими недостатками обладает.
- Сообщения: 2089
- Зарегистрирован: Вс июн 19, 2016 09:32:03
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3709344#p3709344"]Почему Вы не ответили на мой прямой вопрос к Вам в классическом примере полиморфизма в C++? Так что будет сравнивать полиморфный шаблон? Указатели или то, на что они указывают? А если речь будет уже о сложных объектах, с тысячами срок кода их реализации?[/uquote]
Функция сравнивает то, что ей передают, если это сишные строки передаваемые как указатели, то программист должен понимать какой будет результат, тем более в описании написано, что для сравнения используется оператор '<'. Если он не понимает, то и без всяких шаблонов может на С написать практически то же самое:
И что С теперь плохой, все дружно перебираемся на паскаль? 
ps. Лично у меня max() совершенно не ассоциируется с функцией сравнивающей строки...
Функция сравнивает то, что ей передают, если это сишные строки передаваемые как указатели, то программист должен понимать какой будет результат, тем более в описании написано, что для сравнения используется оператор '<'. Если он не понимает, то и без всяких шаблонов может на С написать практически то же самое:
Код: Выделить всё
char *s = ("last" > "first") ? "last" : "first";ps. Лично у меня max() совершенно не ассоциируется с функцией сравнивающей строки...
Reflector, наконец-то! А для того, чтобы понимать, нужно исследовать перегрузку оператора сравнения для классов используемых объектов. А если этот код писало десять человек три года назад, быстрее будет без всякого полиморфизма написать свое сравнение, чем копаться в тысячах строках кода, врубаясь, подходит реализованная кем-то когда-то перегрузка для данного случая или нет.
Даже в описанном мной классическом случае совершенно неоднозначно, требуется сравнение указателей или строк. Иногда важно одно, иногда - другое.
Я нигде не писал "плохой", в отличии от Вас. Я только пытаюсь предупредить читателей данной темы, особенно новичков, что ad-hoc полиморфизм в C++ имеет весомые недостатки. Его использовать допустимо только хорошо отдавая себе отчет, что вернувшись к своему же коду через год-другой понадобится углубляться в изучение реализации всех перегрузок давно забытого кода.
В общем случае, лучше начинающим вообще на C++ полиморфизмом не увлекаться. Код будет прозрачней и проще.
Даже в описанном мной классическом случае совершенно неоднозначно, требуется сравнение указателей или строк. Иногда важно одно, иногда - другое.
Я нигде не писал "плохой", в отличии от Вас. Я только пытаюсь предупредить читателей данной темы, особенно новичков, что ad-hoc полиморфизм в C++ имеет весомые недостатки. Его использовать допустимо только хорошо отдавая себе отчет, что вернувшись к своему же коду через год-другой понадобится углубляться в изучение реализации всех перегрузок давно забытого кода.
В общем случае, лучше начинающим вообще на C++ полиморфизмом не увлекаться. Код будет прозрачней и проще.
- Сообщения: 3386
- Зарегистрирован: Пн окт 11, 2010 19:00:08
- Сообщения: 3604
- Зарегистрирован: Пн июл 28, 2008 22:12:01
Мурик, тебе давно пора. Сидел на барсиках и нечего было слезать. Только СД мог такое за переход на барсик ляпнуть...
- Сообщения: 2516
- Зарегистрирован: Пт июл 12, 2019 22:52:01
[uquote="Reflector",url="/forum/viewtopic.php?p=3709209#p3709209"]Как ты на С будешь делать подобные проверки?[/uquote]
Не буду. Это - блажь!
Не буду. Это - блажь!
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Я на гитхабе, в ЖЖ
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3709344#p3709344"]Так что будет сравнивать полиморфный шаблон? Указатели или то, на что они указывают? А если речь будет уже о сложных объектах, с тысячами срок кода их реализации?[/uquote]Средства языка позволяют понять что за тип передаётся в шаблон и либо подобрать ему соответствующий метод сравнения, либо assert-нуть. Если программист этого не сделал, то он ССЗБ.
Добавлено after 7 minutes 10 seconds:
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=3709507#p3709507"]Не буду. Это - блажь![/uquote]Ваше мнение очень важно для нас!
Добавлено after 7 minutes 10 seconds:
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=3709507#p3709507"]Не буду. Это - блажь![/uquote]Ваше мнение очень важно для нас!
- Сообщения: 2089
- Зарегистрирован: Вс июн 19, 2016 09:32:03
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3709595#p3709595"]и что будет сравниваться в моем простейшем примере? )))[/uquote]
Если бы изначально в С параллельно с char существовал еще один 8-ми битный тип, условный byte, и char использовался только для строк, то max() принимая char* могла бы исходить из того, что это строки, сравнивать их нужно как строки и нет никаких проблем. Внимание вопрос: а при чем тут параметрический полиморфизм на мономорфном ядре?
Ты пытаешься убедить, что проблема в С++, т.к. полиморфизм там какой-то недоделанный, но даже идеальная реализация полиморфизма бесполезна когда нельзя сказать строка перед нами или что-то другое...
Если бы изначально в С параллельно с char существовал еще один 8-ми битный тип, условный byte, и char использовался только для строк, то max() принимая char* могла бы исходить из того, что это строки, сравнивать их нужно как строки и нет никаких проблем. Внимание вопрос: а при чем тут параметрический полиморфизм на мономорфном ядре?
Reflector, я никого не убеждаю, я просто констатирую факт, что в С++ нет параметрического полиморфизма, как, например, в ML. Вместо этого есть синтаксический сахар ad-hoc полиморфизма поверх мономорфного ядра. Именно из этого мономорфного ядра и проистекают все недостатки полиморфизма в C++. Полиморфизм в C++ не может быть "доделанным". Для этого нужно сменить ядро языка на полиморфное, но тогда это будет уже другой язык )
Добавлено after 18 minutes 38 seconds:
P.S. У меня складывается ощущение, что многие просто не понимают, что такое полиморфизм. На удивление, в Вики очень неплохая статья по этому поводу.
Добавлено after 18 minutes 38 seconds:
P.S. У меня складывается ощущение, что многие просто не понимают, что такое полиморфизм. На удивление, в Вики очень неплохая статья по этому поводу.


