LINUX.ORG.RU

Может кто нибудь показать красоту с++?

 ,


7

9

Может кто нибудь написать на c++, чтобы показать почему c++ лучше смотрится чем программа на си? Хотелось бы увидеть изящный код на c++, так, как это делают с хорошим опытом. Программу любую, главное чтобы было понятно, что c++ намного красивее в написании, чем си.

Ответ на: комментарий от t184256

Блин, я вообще-то на работе пишу наукоемкие числодробилки.

Тогда с вами все ясно.

eao197 ★★★★★
()
Ответ на: комментарий от t184256

в моделировании плазменного кильватерного ускорения

нету нужды в фичах именно C++ у наукоемких числодробилок.

Можно подумать, что числодробилка вообще - это только «наукоемкие числодробилки», а наукоемкие числодробилки - это исключительно «моделирование плазменного кильватерного ускорения», которые пишет один лоровский анонимус.

tailgunner ★★★★★
()
Ответ на: комментарий от eao197

Там очень дешевые абстракции.

Ага, как китайский дождевик — тонко, дешево, прозрачно, рвется на каждый чих, штопать не принято, в цивилизованном обществе тупо выкидывают и покупают куртку.

И за которыми можно прятать все, что угодно, хоть использование специализированных процессорных инструкций, хоть делегирование вычислений на специализированные устройства. Плюс шаблоны. Плюс специализация шаблонов. Плюс expression templates на этих же самых шаблонах.

А чем-то уникальным и отличным от нарушения принципа наименьшей неожиданности через слоеную задницу C++ похвастать может?

Тем не менее, так оно и есть. C++ широко используется в разработке таких ОС, как Windows и macOS.

Le-ga-cy.

IncludeOS

Бог им судья.

чего там сейчас делает Google.

Mixed: C, C++, Dart, Go, Rust, Python, Swift

Зачем <во встраиваемом ПО> именно C++? Непонятно.

Если вам что-то не понятно, то это не означает, что встраиваемое ПО на C++ не делается. Или что использование C++ там не выгодно. Выгодно. Как раз за счет тех же шаблонов, RAII, лямбд и более строгой типизации, чем в C.

Допускаю. Память сейчас дешевая, может и рантайм плюсов входит.

Затем, что <видеоредактор> это a) нехилая числодробилка

И что она, простите, дробит на C++?

и b) у нее высокие требования к отзывчивости.

С играми путаешь.

Вообще, ощущение, что разговариваю с пришельцем из параллельной вселенной только усиливается. Хорошо, если не с пациентом палаты №6.

Вот сходишь на ЛОР набросить цивильненько, а там сначала модер тебя психом обзовет, теперь ты. ЧЯДНТ?

t184256 ★★★★★
()
Ответ на: комментарий от tailgunner

Можно, тебе сегодня все можно. Обязательно перепишем специально для тебя на C++ весь софт для GPU, все видеокодеки, всю криптографию, только не заводись.

t184256 ★★★★★
()
Ответ на: комментарий от t184256

ЧЯДНТ?

Ты жрешь тайд, очевидно же.

Обязательно перепишем специально для тебя на C++ весь софт для GPU, все видеокодеки, всю криптографию

Тебе столько тайда не сожрать.

tailgunner ★★★★★
()
Ответ на: комментарий от t184256

Ага, как китайский дождевик — тонко, дешево, прозрачно, рвется на каждый чих, штопать не принято, в цивилизованном обществе тупо выкидывают и покупают куртку.

Доказательство по аналогии? Говорю же, иксперд, аргументация такая, что не оспорить.

А чем-то уникальным и отличным от нарушения принципа наименьшей неожиданности через слоеную задницу C++ похвастать может?

Вашу анальную боль от неспособности осилить C++ понять можно. Проблема в том, что анальная боль не может восприниматься в качестве аргумента в техническом споре. Жизнь показала, что в C++ хороший набор возможностей для написания эффективного кода. Вы можете от этого отмахнуться и поискать альтернативу, вдруг да получится.

может и рантайм плюсов входит.

Во встраиваемом ПО можно использовать ну очень сильно урезанный рантайм плюсов. Что, собственно говоря, многие и делают. Что характерно, вышеуказанные мной фичи, вроде шаблонов, RAII и лямбд, от этого ничуть не теряют.

И что она, простите, дробит на C++?

Изображение. Цветокоррекция, накладывание масок/фильтров, масштабирование, добавление эффектов — это все числодробилки.

Может не такие наукоемкие, как «моделирование плазменного кильватерного ускорения», но вполне себе тяжелые.

С играми путаешь.

Не приписывайте мне своих заблуждений. У профессионального софта для обработки фото и видео вполне себе большие требования к отзывчивости. Ибо ждать по 5 секунд пока появится превью наложенного эффекта профи не будут, для них паузы в работе — это деньги.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

ждать по 5 секунд пока появится превью

Для такой отзывчивости и язык с GC сойдет, особенно когда горячий код не на нем.

Ладно, подытожим.

Реалтайм и индустриальная эмбедщина — хорошие аргументы, урезонил мальца, хвалю. Тут пользу от C++ представить нетрудно.

ОСи меня не впечатлили, видеоредактор совсем мимо, так как числа дробят там не плюсы.

Приложения с тяжелой логикой, действительно, принято сейчас писать на плюсах, потому что новомодные альтернативы еще непопулярны. Тут тоже хрен поспоришь, но и заслугой тому не стройность и элегантность плюсов, а их популярность.

Общие слова на ветер не кидай, в техническом споре они так же весомы, как и моя «анальная боль». Боль от C++ у меня действительно есть, но, боюсь, не от неспособности осилить, а скорее наоборот.

В целом было интересно, но опусти ты сомнительные ниши и поменьше переходи на личности, было бы еще интереснее. Спасибо!

t184256 ★★★★★
()
Последнее исправление: t184256 (всего исправлений: 1)
Ответ на: комментарий от t184256

видеоредактор совсем мимо, так как числа дробят там не плюсы.

Сам с видеоредакторами дел не имел (хотя и наслышан об их разработке), а вот с Lightroom для обработки фото дело имел плотно (и с CaptureOne отчасти). Не нужно рассказывать сказки про то, что там числа дробит. И про отзывчивость такого рода софта.

eao197 ★★★★★
()
Ответ на: комментарий от t184256

В числодробилках для решения трёхмерных задач газовой динамики, из того что мне попадалось, чаще используется C++. И там не только расширения файлов.

Ещё видел код на Fortran, но на тот момент там продолжали использовать в основном 77, так как либо не знали новые фичи, либо считая, что переписывание готового кода никак не ускорит решение. Параллелилось это всё, естественно, напрямую через mpi, а не через встроенные в новые версии языка фичи.

И когда я рылся в разных темах на reseachgate на предмет того, как часто сейчас используют фортране, то обычно отписывались те, кто перешёл на C++. Если они при этом не используют фичи C++, и пишут на чистом C, то это какие-то ССЗБ, так как современный Fortran намного удобнее чистого C.

grem ★★★★★
()
Ответ на: комментарий от fsb4000

Этим и крут С++

Лол :-) Крутость в том, что вместо 3-х крохотных строчек на ассемблере, на цепепе надо написать простынь из 25? :-)

azelipupenko
()
Ответ на: комментарий от eao197

Во встраиваемом ПО можно использовать ну очень сильно урезанный рантайм плюсов. Что, собственно говоря, многие и делают. Что характерно, вышеуказанные мной фичи, вроде шаблонов, RAII и лямбд, от этого ничуть не теряют.

Как то странно. Значится, рантайм плюсов урезается, чтобы впихнуть программу во микроустройство, но шаблоны, провоцирующие распухание кода, остаются...

Вот мне не понятен этот подход. Допустим, нужно разработать прошивку под какой-то микродевайс. Принимается решение использовать плас-плас с урезанным рантаймом. Потом, значится, начинается использование шаблонов - тут, там, здесь... Ну и как, глядя на шаблоны, оценивать размер кода, который нагенерит плас-плас компилятор? Это какое-то тайное искусство? Или это искусство на уровне метода тыка - «авось уместится, мы же урезали рантайм, так что должно взлететь!».

Далее, лямбды. На кой, простите, хрен они нужны во встраиваемых системах? Нет, фича интересная, особенно для обсуждения на конференциях. Но в эмбедде зачем лямбды? Т.о. образом, главная фича ++, которая может быть осмысленно использована в эмбедде, - - это деструкторы. Всё остальное сомнительные финтифлюшки чисто для поиграться.

azelipupenko
()
Ответ на: комментарий от Meyer

Нет, я не о дум3.

Я считаю что у каждого проекта должна быть своя идеология, какой бы безумной и неоправданной она не была. Только тогда он сможет не скатываться в говнокод. Будь то надрачивание на «крестовость» кода, или же совсем наоборот.

К первым у меня чисто субъективная неприязнь. Для меня С++ это именно пост-инкремент Си, то бишь почти всё тот же Си с иногда полезными, иногда сомнительными надстройками сверху. Которыми же никто меня не обязывает пользоваться и это хорошо.

a1batross ★★★★★
()
Ответ на: комментарий от azelipupenko

но шаблоны, провоцирующие распухание кода, остаются...

Какое-нибудь подтверждение этому мифу будет?

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Какое-нибудь подтверждение этому мифу будет?

Будет. Оно приведено в главной книге Страуструпа. В 4-м издании глава идёт под номером 25.3, в 3-м издании глава имеет номер 13.5. Там автор рассказывает как уменьшить это самое распухание кода при инстанцировании шаблона вектора путём использования полной специализации Vector<void*>. Кто-то скажет - вот она, серебряная пуля, какое-такое распухание кода. Однако, сами танцы вокруг специализаций Vector<void*> уже намекают на то, что там, где каждый байт имеет значение, применение шаблонов - просто поле для экспериментов, а не для осмысленной работы.

azelipupenko
()
Ответ на: комментарий от azelipupenko

Потому что на выходе будет тормозящая Unity-школоподелка, а разработчики-геймдевелоперы почесав голову, всё равно перейдут на C++ и Unreal.

https://3dnews.ru/948588

EXL ★★★★★
()
Последнее исправление: EXL (всего исправлений: 1)
Ответ на: комментарий от azelipupenko

Пример из книги известный, я тоже хотел написать. Однако, если на C все контейнеры для используемых T* вручную написать, это типа меньше места займёт что ли или что? Или удастся что-то сэкономить за счёт выделения общих блоков кода? Но чем тогда это отличается от наследования от Vector<void*>?

d_a ★★★★★
()
Ответ на: комментарий от azelipupenko

Потому что тот же движок Unity встанет раком, если его нагрузить так же, как, скажем Frostbite 3. Хотя для простых игр можно использовать, а для игр уровня майнкрафта так вообще хорошо будет.

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 1)
Ответ на: комментарий от d_a

Однако, если на C все контейнеры для используемых T* вручную написать

Во-первых, я не призываю писать на C. C - достойный язык и замены ему нет. Писать ли на C++ вместо C или не писать - дело каждого. Кому что удобнее, тот пусть на том и пишет. Я за это.

Во-вторых. Например, не обязательно Vector<void*>. Можно взять Vector<Vundervafla> с полем типа. И в рантайме проверять. Да, да, да, знаю, знаю: «тормоза во время выполнения», «процессор нагревается при выполнении if (o.type() == Integer)», «ты что, теряется типобезопасность, ужас ужас!!11» и т.п. Но решается практическая задача - экономия памяти.

azelipupenko
()
Ответ на: комментарий от peregrine

Хотя для простых игр можно использовать, а для игр уровня майнкрафта так вообще хорошо будет.

Итак, для простых игр C++ ненужен и достаточно C#?

azelipupenko
()
Ответ на: комментарий от azelipupenko

А вот у шаблонной функции min() какое распухание кода?

Или у for_each-а с лямбдой насколько кода будет больше, чем у записанного вручную for-а?

Или, например, вот такой код:

template<typename Container, typename Lambda>
void for_each_item(Container && c, Lambda && l) {
  std::for_each(std::begin(c), std::end(c), std::forward<Lambda>(l));
}
...
for_each_item(current_values, [](auto & v) { v = 0; });
насколько он будет объемнее вручную записанного for-а?

Или насколько больше накладных расходов у вас будет при использовании std::array<std::uint_8, 256> в сравнении с uint8_t[256]?

PS. Правильно ли я понимаю, что про программирование на C++ вы знаете только по книге «Язык программирования С++»?

eao197 ★★★★★
()
Последнее исправление: eao197 (всего исправлений: 1)
Ответ на: комментарий от azelipupenko

if (o.type() == Integer)

И что, код для поддержки разных типов в рантайме ничего не стоит и места не занимает, да? Хранить разные типы в одном широчайшем ничего не стоит и места не занимает, да?

d_a ★★★★★
()
Ответ на: комментарий от eao197

насколько он будет объемнее вручную записанного for-а?

Именно это в этом и вопрос. В этом и проблема шаблонов. Никто не ответит на этот вопрос, пока не увидит выхлоп конкретного компилятора.

Или насколько больше накладных расходов у вас будет при использовании std::array<std::uint_8, 256> в сравнении с uint8_t[256]?

Тут никаких накладных расходов, скорее всего, не будет.

PS. Правильно ли я понимаю, что про программирование на C++ вы знаете только по книге «Язык программирования С++»?

Нет, не правильно.

azelipupenko
()
Ответ на: комментарий от d_a

И что, код для поддержки разных типов в рантайме ничего не стоит и места не занимает, да?

Занимает, но его объём можно хотя бы приблизительно оценить.

Хранить разные типы в одном широчайшем ничего не стоит и места не занимает, да?

Занимает. Но можно точно оценить объём занимаемой памяти, ибо sizeof(VARIANT) всегда известен. И размер Vector<VARIANT>, следовательно, всегда очевиден.

azelipupenko
()
Ответ на: комментарий от azelipupenko

Там и Pythhon-а может хватить, если игра 2D и запускается на суперкомпьютере.

peregrine ★★★★★
()
Ответ на: комментарий от azelipupenko

Никто не ответит на этот вопрос, пока не увидит выхлоп конкретного компилятора.

Полагаю, каждый C-шник, написав for на 5 строчек, сразу же предскажет размер результирующего бинарного кода для него?

Прям день акуительных открытий.

Тут никаких накладных расходов, скорее всего, не будет.

Но сказки про стоимость шаблонов рассказывать все равно будем.

Нет, не правильно.

Тогда откуда столько херни в голове?

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Полагаю, каждый C-шник, написав for на 5 строчек, сразу же предскажет размер результирующего бинарного кода для него?

Смотря что за for. Если вот такой:

for (int i = 0; i < size; ++i) {
  if (!callback(i)) {
    free(something);
    return -1;
  }
}
то легко.

Но сказки про стоимость шаблонов рассказывать все равно будем.

Это претензия к автору Си++, должно быть.

Тогда откуда столько херни в голове?

У кого? У Страуструпа?

azelipupenko
()
Ответ на: комментарий от azelipupenko

Но можно точно оценить объём занимаемой памяти, ибо sizeof(VARIANT) всегда известен. И размер Vector<VARIANT>, следовательно, всегда очевиден.

А sizeof(int) неизвестен что ли? Или sizeof(char) неизвестен? Что такое размер Vector<VARIANT> (который аллоцирует элементы динамически)? Я понимаю что ещё праздник, но что за ахинею ты несёшь?

d_a ★★★★★
()
Ответ на: комментарий от d_a

А sizeof(int) неизвестен что ли? Или sizeof(char) неизвестен?

Неизвестен общий размер генерируемого кода на шаблонах, инстанцируемого в каждой единицы трансляции.

Что такое размер Vector<VARIANT>

Это размер вектора вариантов. А что?

Я понимаю что ещё праздник, но что за ахинею ты несёшь?

Ну так скажи что-нибудь по существу. Не ахинею, так сказать. А что что-то совсем ни о чём.

azelipupenko
()
Ответ на: комментарий от azelipupenko

На кой, простите, хрен они нужны во встраиваемых системах?

Зачем они нужны в не-встраиваемых системах - понятно? Во встраиваемых - ровно для того же.

Неизвестен общий размер генерируемого кода на шаблонах, инстанцируемого в каждой единицы трансляции.

А известно, что линкер объединяет одинаковые тела функций?

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от azelipupenko

Если вот такой...то легко.

Я вас разочарую. Легко это будет разве что для опытного C-шника, который долго пользуется конкретным компилятором для конкретной платформы. И то, при условии, что в коде кто-то макросами и директивами always_inline не злоупотребил.

Среднестатический не сможет. Тем более из тех, кто недавно вошел-в-ойти на волне высоких зарплат.

Это претензия к автору Си++, должно быть.

Это претензии к вам, как к человеку, который говорит о вещах, в которых мало разбирается (по крайней мере такое впечатление производит).

У кого?

У вас.

eao197 ★★★★★
()
Ответ на: комментарий от grem

И там не только расширения файлов.

А что, если не секрет? ООП в горячем коде? Высокоуровневая логика?

И когда я рылся в разных темах на reseachgate на предмет того, как часто сейчас используют фортране, то обычно отписывались те, кто перешёл на C++.

Может дело в запросе? Молодая хипстота вроде меня, пилящая проекты на питоне, редко переходит с Фортрана. Я однажды переходил, но нигде об этом не писал.

так как современный Fortran намного удобнее чистого C.

И оба они удобнее ассемблера. Только накой сравнивать языки, в которых банальные (array1 + array2) / 2, arr -= arr[-1] или arr.T = transform(arr[::-1].T) требуют несколько отдельных строк? Разве это жизнь?

t184256 ★★★★★
()
Ответ на: комментарий от tailgunner

Зачем они нужны в не-встраиваемых системах - понятно?

Не понятно.

А известно, что линкер объединяет одинаковые тела функций?

Не известно. Линкер линкеру рознь.

azelipupenko
()
Ответ на: комментарий от eao197

Я вас разочарую.

Нет. Я ведь не был очарован.

Среднестатический не сможет.

Он сможет несколько иное. Опытным путём. Нужно просто скомпилить код с шаблонами и его эквивалент без шаблонов и сравнить размеры бинарей. Это сможет любой.

Это претензии к вам, как к человеку, который говорит о вещах, в которых мало разбирается (по крайней мере такое впечатление производит).

Тоже самое можно сказать и про вас. Вы - человек, который говорит о вещах, в которых мало разбирается (по крайней мере такой впечатление производит).

У вас.

У вас. У вас хорошо развито чувство соперничества. Ваш стиль общения довольно агрессивный с переходом на личности. Становитесь ли вы от этого более убедительны? Нет. Поднимает ли это ваш авторитет или репутацию? Нет. Влияет ли это на моё мнение? Нет.

azelipupenko
()
Ответ на: комментарий от azelipupenko

На кой, простите, хрен они нужны во встраиваемых системах?

Зачем они нужны в не-встраиваемых системах - понятно?

Не понятно.

Тогда задавай правильные вопросы: «На кой хрен вообще нужны лямбды?». А пока не найдешь ответа на этот вопрос - можешь использовать другие средства Си++. Если понимаешь, зачем они нужны.

А известно, что линкер объединяет одинаковые тела функций?

Не известно. Линкер линкеру рознь.

Известно, что линкеры GCC и Keil это делают. Если у тебя другой линкер - почитай его документацию.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от tailgunner

Тогда задавай правильные вопросы: «Я вообще не понимаю, зачем нужны лямбды». А пока не найдешь ответа на этот вопрос

Это не вопрос, а утверждение.

Известно, что линкеры GCC и Keil это делают. Если у тебя другой линкер - почитай его документацию.

А MSVC делает?

azelipupenko
()
Ответ на: комментарий от azelipupenko

Тогда задавай правильные вопросы: «Я вообще не понимаю, зачем нужны лямбды». А пока не найдешь ответа на этот вопрос - можешь использовать другие средства Си++.

Это не вопрос, а утверждение.

Если ты не знаешь, зачем нужны лямбды - я уже сказал, что делать.

Известно, что линкеры GCC и Keil это делают. Если у тебя другой линкер - почитай его документацию.

А MSVC делает?

А зачем это знать при разработке встраиваемой системы? Впрочем, если тебе это нужно знать, то я уже сказал, как это узнать.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Сам спросил:

А известно, что линкер объединяет одинаковые тела функций?

Сам ответил:

А зачем это знать при разработке встраиваемой системы? Впрочем, если тебе это нужно знать, то я уже сказал, как это узнать.

Если ты не знаешь, зачем нужны лямбды - я уже сказал, что делать.

Они нужны для автогенерации функторов. Но это не та фича си++, которую можно приводить как преимущество перед Си.

azelipupenko
()
Ответ на: комментарий от azelipupenko

Опытным путём.

В том-то и суть. Как только вы перестаете писать на голом ассемблере и начинаете использовать язык более-менее высокого уровня, вы можете узнать про стоимость своего кода разве что опытным путем. Причем чем больше развиваются оптимизирующие компиляторы, тем дальше вы можете оказаться в своих предположениях.

И шаблоны здесь постольку-поскольку.

Нужно просто скомпилить код с шаблонами и его эквивалент без шаблонов и сравнить размеры бинарей.

Ну вот расскажите о своем опыте. Как вы скомпилировали код с шаблонами и без, что получилось. Что это были за шаблоны и т.д.

Сможете?

Ваш стиль общения довольно агрессивный с переходом на личности.

Если личности отнимают время своей тупизной и нежеланием говорить по делу, то не грех на это указать.

Поднимает ли это ваш авторитет или репутацию?

О чем вы вообще? Кому эти вещи в Интернетах сдались?

Влияет ли это на моё мнение?

А кого интересует ваше мнение? Важно что вы говорите по теме, т.е. о C++. Пока вы пересказываете какие-то городские легенды из середины 1980-х годов.

eao197 ★★★★★
()
Ответ на: комментарий от azelipupenko

Они нужны для автогенерации функторов.

А еще как эмуляция локальных функций, например.

eao197 ★★★★★
()
Ответ на: комментарий от azelipupenko

Не понял, зачем ты намешал цитат из разных постов, но скажи - как там линкер MSVC, объединяет одинаковые шаблонные функции или нет?

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от azelipupenko

для простых игр даже компьютер не нужен: достаточно авторучки и листка бумаги

next_time ★★★★★
()
Ответ на: комментарий от azelipupenko

Смотря что за for. Если вот такой:

...то у вас тут undefined behaviour и поведение зависит от версии компилятора, т.е. предсказать его очень даже не легко, и, в общем случае, невозможно

next_time ★★★★★
()
Ответ на: комментарий от t184256

А что, если не секрет? ООП в горячем коде? Высокоуровневая логика?

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

Может дело в запросе? Молодая хипстота вроде меня, пилящая проекты на питоне, редко переходит с Фортрана. Я однажды переходил, но нигде об этом не писал.

Вряд ли переход с фортрана на C++ был у молодой хипстоты.

Только накой сравнивать языки, в которых банальные (array1 + array2) / 2, arr -= arr[-1] или arr.T = transform(arr[::-1].T) требуют несколько отдельных строк? Разве это жизнь?

Если имеются ввиду действия с марицами (пусть 2x2), то в фортране будет как

(arr1 + arr2 ) /2
arr1 = arr1 - arr1(2:1:-1, 2:1:-1)

в последней строчке я сходу не понял, что имеется ввиду, лезть проверять как это выглядит на питоне (если имеется ввидуон) лень :(

grem ★★★★★
()
Ответ на: комментарий от grem

Вряд ли переход с фортрана на C++ был у молодой хипстоты.

Вот и я о том же. Искал бы переход на Python, нашел бы переход на Python.

Если имеются ввиду действия с марицами (пусть 2x2)

Многомерными массивами NxMxK, но и так интересно.

t184256 ★★★★★
()
Ответ на: комментарий от eao197

Сможете?

Не вопрос.

Общий код:

prog.cpp:

extern void f();
extern void g();

int main()
{
  f();
  g();
}

Теперь напишем класс Variant и шаблон класса Variant, а так же функции f() и g(), которые будут использовать эти класс и шаблон. Определим их в разных единицах трансляции. Поехали.

Не шаблоны:

variant1.hpp:

#ifndef VARIANT1
#define VARIANT1

struct Variant {
  enum class Type {
    Integer,
    Double
  };

  union Value {
    Value(int i) : i_{i} {}
    Value(double d) : d_{d} {}
    int i_;
    double d_;
  };

  Variant(Value value, Type type);

  Value get() const;

  void print_info();

  Value value_;
  Type type_;
};

#endif

variant1.cpp:

#include "variant1.hpp"

#include <iostream>
#include <typeinfo>

Variant::Variant(Value value, Type type) : value_{value}, type_{type}
{}

auto Variant::get() const -> Value { return value_; }

void Variant::print_info()
{
  std::cout << "value = " << ((type_ == Type::Integer) ? value_.i_ : value_.d_) << "\n";
  std::cout << "type = " << ((type_ == Type::Integer) ? typeid (value_.i_).name() : typeid (value_.d_).name()) << "\n";
}

f1.cpp:

#include "variant1.hpp"

#include <cstdio>

void f()
{
  Variant v1(Variant::Value(1), Variant::Type::Integer);
  Variant v2(Variant::Value(2.1), Variant::Type::Double);

  std::printf("int = %i double = %f\n", v1.get().i_, v2.get().d_);
  v1.print_info();
  v2.print_info();
}

g1.cpp:

#include "variant1.hpp"

#include <cstdio>

void g()
{
  Variant v1(Variant::Value(1), Variant::Type::Integer);
  Variant v2(Variant::Value(2.1), Variant::Type::Double);

  std::printf("int = %i double = %f\n", v1.get().i_, v2.get().d_);
  v1.print_info();
  v2.print_info();
}

Шаблоны:

variant2.hpp:

#ifndef VARIANT2
#define VARIANT2

#include <iostream>
#include <typeinfo>
#include <utility>

template<typename T>
struct Variant {
  Variant(T value) : value_{std::forward<T>(value)}
  {}

  const T& get() const { return value_; }

  void print_info()
  {
    std::cout << "value = " << value_ << "\n";
    std::cout << "type = " << typeid (value_).name() << "\n";
  }

  T value_;
};

#endif

f2.cpp:

#include "variant2.hpp"

#include <cstdio>

void f()
{
  Variant v1{1};
  Variant v2{2.1};

  std::printf("int = %i double = %f\n", v1.get(), v2.get());
  v1.print_info();
  v2.print_info();
}

g2.cpp:

#include "variant2.hpp"

#include <cstdio>

void g()
{
  Variant v1{1};
  Variant v2{2.1};

  std::printf("int = %i double = %f\n", v1.get(), v2.get());
  v1.print_info();
  v2.print_info();
}

Компиляем и проверяем:

$ g++ -O3 -flto -std=c++1z prog.cpp variant1.cpp f1.cpp g1.cpp -oprog1
$ g++ -O3 -flto -std=c++1z prog.cpp f2.cpp g2.cpp -oprog2
$ ls -nl prog1 prog2
-rwxrwxr-x 1 1000 1000 9744 фев 24 22:57 prog1
-rwxrwxr-x 1 1000 1000 9872 фев 24 22:57 prog2

Разница для такого хелловорлда - 128 байт. Для встроенных систем это может иметь значение, если там не хелловорлд. Но, шаблоны таки дуют код :-)

PS. Если в нешаблонном варинате отказаться от type_info (т.к. уже есть поле типа), то разница была бы ещё больше.

PS2. Конечно, надо отдать должное разработчикам GCC. Честно говоря, я не ожидал увидеть такой маленький разрыв! Ну что тут можно сказать. Я очень рад за C++! :-)

azelipupenko
()
Ответ на: комментарий от tailgunner

Не понял, зачем ты намешал цитат из разных постов, но скажи - как там линкер MSVC, объединяет одинаковые шаблонные функции или нет?

Как-нибудь в другой раз скажу :-) Точнее, проверю. Тест кейс, который постом выше есть, так что проверю как-нибудь кто круче, GCC или MSVC в этом плане.

azelipupenko
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.