Re[6]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 12:11
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>В других языках просто выбрали удобство за счёт небольшой платы.


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

K>В С++ и в стандартных библиотеках на тех же виртуальных вызовах экономят, что закономерно идёт как рекомендация.


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

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

K>Я помню ещё холивары на счёт исключений. Одни писали, что этот механизм крутой и удобный. Другие топили за коды ошибок, т.к. исключение — это же создание объекта и прочие непозволительно дорогие накладные расходы.


А с этим проблема в том, что нет механизмов, промежуточных по сложности и накладным расходам. Коды ошибок приходится распространять наверх почти целиком вручную, мало что можно приспособить для автоматизации — в основном лишь для ловли собственных ошибок. Добавление исключений сразу же тянет за собой и механизмы создания/копирования объектов исключений, и RTTI, а между этими крайностями ничего нет. Во многих случаях было бы достаточно какого-нибудь легковесного механизма, передающего наверх только фундаментальные типы (простые значения или указатели).

K>На мой взгляд для большинства софта подобная экономия на спичках (виртуальных методах) вообще незаметна. Но если по такому не упарываться, то непонятно зачем на C++ писать, а не взять что-то более удобное


Идея разумная. Но удобство C++ как раз в том, что на нем можно писать всё.
Re[7]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 05.08.24 12:18
Оценка: -2 :))
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Но удобство C++ как раз в том, что на нем можно писать всё.


Евгений, блин, уже лет 20 как пора забыть про эту чушь.
Re[7]: Об эффективности виртуальных функций
От: · Великобритания  
Дата: 05.08.24 12:21
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ> В такой ситуации в полный рост встает вопрос о разнесении разных типов по собственным контейнерам, чтобы вынести проверку типа как можно выше. Но это, понятно, только после измерений на конкретных задачах.

Так контейнеры не просто так контейнят, а в соответствии с бизнес-логикой, например, упорядоченно по времени обработки.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[2]: Об эффективности виртуальных функций
От: andyp  
Дата: 05.08.24 12:54
Оценка: +1
Здравствуйте, karbofos42, Вы писали:

K>Удобно ведь было бы в метод принимать просто коллекцию, получать какой-то абстрактный итератор для перебора или через виртуальный метод add добавить пару элементов.

K>Вместо этого приходится писать методы конкретно под std::vector и никакой std::set не передашь.

Как должен выглядеть такой обобщенный add для vector и set? Куда и что он втыкать будет — не понятно. С абстрактным итератором тоже неясно — как это будет работать и где гарантии, что ты посетишь все элементы коллекции. Да даже просто изменение элементов в одном случае структуру коллекции не меняет, а в другом — меняет. Т.е. имхо пока даже почвы для обобщения немного. Если твои функции предполагают, что коллекция в процессе не меняется, то любая вьюха (наверное, на языке стандарта это называется range???), состоящая из пары итераторов или еще чего — подойдет, чтобы пробежаться по всем элементам. Зачем для этого иметь общий интерфейс — я , но то путь явы и шарпов.
Re[3]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 13:27
Оценка: +1 :)
Здравствуйте, andyp, Вы писали:

A>Как должен выглядеть такой обобщенный add для vector и set? Куда и что он втыкать будет — не понятно.


Это очень просто решается путём документирования поведения, что для vector этот самый add — это добавление в конец коллекции, для set всё проще и это тот же insert.
В тех же шарпах и явах с этим живут и проблем не испытывают.

A>С абстрактным итератором тоже неясно — как это будет работать и где гарантии, что ты посетишь все элементы коллекции.


Так же как и сейчас работает. Просто вызываться будут виртуальные методы некоего базового итератора, а фактически реализация будет та же, что сейчас.

A>Да даже просто изменение элементов в одном случае структуру коллекции не меняет, а в другом — меняет.


И как это сейчас работает? Просто программист имеет знания и вручную следит или волшебство С++ работает какое-то?
Что тут изменится, если у коллекций и итераторов появятся общие базовые классы?

A>Т.е. имхо пока даже почвы для обобщения немного.


Ну, да. В других языках как-то обобщилось, а в С++ — никак. Я и говорю, что это упоротая идеология языка.
Распихать по стандарту кучу UB — легко. Добавить в синтаксис языка кучу возможностей опечататься и выстрелить себе в ногу — пожалуйста.
Договориться, что collection.add() для вектора — это аналог метода push_back — непонятно как с этим потом жить.

A>Если твои функции предполагают, что коллекция в процессе не меняется, то любая вьюха (наверное, на языке стандарта это называется range???), состоящая из пары итераторов или еще чего — подойдет, чтобы пробежаться по всем элементам. Зачем для этого иметь общий интерфейс — я , но то путь явы и шарпов.


А если нужно добавлять элементы в коллекцию? А вьюхи бесплатные и удобные, чтобы такое городить? Не выходит в итоге, что с общим интерфейсом и виртуальными методами работа с коллекцией была бы быстрее и удобнее, чем создавать вьюхи и пробираться через них? Но такой путь плюсов
Re[4]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 05.08.24 13:40
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Ну, да. В других языках как-то обобщилось, а в С++ — никак. Я и говорю, что это упоротая идеология языка.


Вы, по видимому, просто не застали первую Java. Там ведь коллекции были нетипизированными в том смысле, что хранился всегда Object. Не важно, запихивали ли вы в коллекцию String или File, или DateTime, все равно там лежал Object. И доставался назад тоже Object, который потом вручную нужно было кастить к нужному вам типу (и получать иногда исключения, если программист забыл что куда укладывал).

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

Только вот в C++ не было базового класса Object.
А значит и коллекции нужно было строить по другому.

Вот и построили их на базе шаблонов.
Re[5]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 14:02
Оценка:
Здравствуйте, so5team, Вы писали:

S>Вы, по видимому, просто не застали первую Java.


И в Java и в C# Generic'и появились не с первой версии, я в курсе. И при всей внешней синтаксической похожести они работают по-разному в этих языках.

S>Только вот в C++ не было базового класса Object.

S>А значит и коллекции нужно было строить по другому.

S>Вот и построили их на базе шаблонов.


И что мешает эти уже шаблонные классы коллекций унаследовать от таких же шаблонных общих базовых классов?
  Вот так в чём проблема сделать?
#include <iostream>

template <typename T>
class collection
{
public:
  virtual void add(T item) = 0;
};

template<typename T>
class vector: public collection<T>
{
public:
  virtual void add(T item)
  {
      std::cout << "vector add " << item << std::endl;
  }
};

template<typename T>
class set: public collection<T>
{
public:
  virtual void add(T item)
  {
      std::cout << "set add " << item << std::endl;
  }
};

void fill_data(collection<int>& items)
{
    items.add(10);
}

int main()
{
    vector<int> v;
    fill_data(v);
    
    set<int> s;
    fill_data(s);

    return 0;
}
Re[5]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 14:04
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Поэтому там, где нужна предельная эффективность, до сих пор преобладают сишники.


Или плюсовики, которые уделяют внимание вопросам производительности.


ЕМ>А плюсовики, изучавшие язык "сверху", вполне могут долгое время сохранять усвоенные когда-то предубеждения, что не мешает им писать достаточно эффективный код способами, которым они доверяют.


И это прекрасно, что язык такое позволяет
Re[4]: Об эффективности виртуальных функций
От: andyp  
Дата: 05.08.24 14:08
Оценка: +1
Здравствуйте, karbofos42, Вы писали:

K>Здравствуйте, andyp, Вы писали:


A>>Как должен выглядеть такой обобщенный add для vector и set? Куда и что он втыкать будет — не понятно.

K>Это очень просто решается путём документирования поведения, что для vector этот самый add — это добавление в конец коллекции, для set всё проще и это тот же insert.
K>В тех же шарпах и явах с этим живут и проблем не испытывают.

И тут бац — и ты написал код, который для разных коллекций работает по разному. А общая функция предполагает, что будет одинаково, вне зависимости от коллекции. Не моё это.

A>>С абстрактным итератором тоже неясно — как это будет работать и где гарантии, что ты посетишь все элементы коллекции.

K>Так же как и сейчас работает. Просто вызываться будут виртуальные методы некоего базового итератора, а фактически реализация будет та же, что сейчас.

Ну сейчас это просто не работает После того, как ты изменил элемент в std::set (erase-insert) тебе обещают, что все твои сохраненные итераторы будут указывать на что-то валидное. Но это не значит, что с их помощью ты обежишь всю коллекцию и ничего не пропустишь.

A>>Да даже просто изменение элементов в одном случае структуру коллекции не меняет, а в другом — меняет.

K>И как это сейчас работает? Просто программист имеет знания и вручную следит или волшебство С++ работает какое-то?
K>Что тут изменится, если у коллекций и итераторов появятся общие базовые классы?

Программист имеет знание, с какой именно коллекцией он работает. Это ж важно.

A>>Т.е. имхо пока даже почвы для обобщения немного.

K>Ну, да. В других языках как-то обобщилось, а в С++ — никак. Я и говорю, что это упоротая идеология языка.
K>Распихать по стандарту кучу UB — легко. Добавить в синтаксис языка кучу возможностей опечататься и выстрелить себе в ногу — пожалуйста.
K>Договориться, что collection.add() для вектора — это аналог метода push_back — непонятно как с этим потом жить.

Договориться — имхо вообще негодный подход. Имхо, Степанов правильно сделал, что не стал делать общий базовый класс для коллекций. Вот почитал доку на Яву и увидел, что их обобщение коллекции это просто нечто, по чему можно итерировать. И все, Карл. Чтобы что-то более значимое запилить, нужно что-то новое о коллекциях понять имхо. Существующее обобщение никак не помогает. Хреновая абстракция, имхо, этот общий базовый класс.

A>>Если твои функции предполагают, что коллекция в процессе не меняется, то любая вьюха (наверное, на языке стандарта это называется range???), состоящая из пары итераторов или еще чего — подойдет, чтобы пробежаться по всем элементам. Зачем для этого иметь общий интерфейс — я , но то путь явы и шарпов.

K>А если нужно добавлять элементы в коллекцию? А вьюхи бесплатные и удобные, чтобы такое городить? Не выходит в итоге, что с общим интерфейсом и виртуальными методами работа с коллекцией была бы быстрее и удобнее, чем создавать вьюхи и пробираться через них? Но такой путь плюсов

А что дорогого в паре итераторов или паре итератор + счетчик? Обобщенный код под такое вполне себе пишется. Сделай своему алгоритму, которому пофиг на тип коллекции, такой интерфейс и дело в шляпе, без всех этих иерархий классов.
Отредактировано 05.08.2024 14:12 andyp . Предыдущая версия .
Re[6]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 14:12
Оценка: +2
Здравствуйте, karbofos42, Вы писали:

K>На мой взгляд для большинства софта подобная экономия на спичках (виртуальных методах) вообще незаметна. Но если по такому не упарываться, то непонятно зачем на C++ писать, а не взять что-то более удобное


В C++ контенеры универсальные. И вполне могут содержать миллионы и более объектов на некоторых задачах. И вполне вероятно, что над этими объектами могут часто производится легкие операции, и тут виртуальность уже может добавить времени.
Ну и, не буду утверждать, но предполагаю, что косвенность мешает оптимизатору
Re[4]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 14:21
Оценка:
Здравствуйте, karbofos42, Вы писали:

BFE>>Впрочем, что мешает написать обёртку, которая будет принимать в конструкторе тип контейнера (или сам контейнер) и выставлять желаемый интерфейс? Такое можно написать за несколько часов без особого труда.


K>В итоге в проекте будет какой-то зоопарк,


Не будет


K>а накладных расходов ещё больше, чем было бы с виртуальными методами изначально.


Компилятор соптимизирует


K>Хотя в плюсах наверно так принято, чтобы веселее было. Один интерфейс как в других языках — не интересно, а вот когда где-то vector, где-то QList или wxVector или ещё какой подобный класс — это весело и замечательно, особенно когда нужно из одного типа в другой данные гонять, т.к. у тебя есть vector, а нужный метод написан для QList.


Наличие vector, QList или wxVector — это проблемы сторонних библиотек. Как будто в других языках такого не может быть.

Не помню по поводу wxWidgets, а Qt приводит свои контейнеры в соответствие плюсовым стандартным, так что обобщенные алгоритмы будут работать и на тех контейнерах, и на других. Просто надо писать обобщённый код, а не код для конкретного контейнера.


K>так и пусть разные будут, лишь бы можно было в итоге написать без шаблонов и обёрток метод вида:

K>
K>void process(collection<int>& items)
K>{
K>  for (auto& value: items)
K>  {
K>    ...
K>  }
K>}
K>

K>и передать туда и std::vector<int> и std::set<int> и QList<int> (при условии конечно, что все они унаследуются от collection<int>)

А в чем проблема писать с шаблонами?


K>Или всё же такое наследование и последующие виртуальные вызовы добавят увеличение потребления памяти, существенно снизит скорость работы и в плюсах так не принято?


Добавят. А существенно или нет — это зависит от задач, и объёмов данных. Не понимаю, зачем это в язык закладывать, а потом героически преодолевать, когда понадобится производительность? Не нравятся плюсы — пиши на шарпе, тебя кто-то заставляет?
Re[3]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 14:26
Оценка:
Здравствуйте, andyp, Вы писали:

A>Как должен выглядеть такой обобщенный add для vector и set? Куда и что он втыкать будет — не понятно.


Ну, для set — это просто insert, для vector — это, скорее всего, push_back.

И хоть навставляйся хоть в set, хоть в vector через std::inserter
Re[6]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 14:46
Оценка: :)
Здравствуйте, пффф, Вы писали:

П>Или плюсовики, которые уделяют внимание вопросам производительности.


Среди профессиональных сишников преобладают те, кто пришел "снизу" — от железа и/или ассемблеров, ибо мало кто из чистых прикладников, привыкнув к современным ЯВУ, станет спускаться к C без крайней нужды. Среди плюсовиков, пришедших в язык "сверху", изначально привыкших к "высокоуровневому" программированию, таких меньшинство. Система отбора, основанная на проверке знания стандартов, способствует тому, что человек умеет писать формально правильный код, но далеко не всегда видит, как именно по нему будет работать реальная машина.

Когда они делают на плюсах прикладной софт общего назначения, который работает заметно быстрее, чем у их коллег на Java/C#, у них может возникнуть ощущение, что они "уделяют внимание вопросам производительности", хотя на самом деле их спасают прежде всего готовые типовые оптимизации (семантика перемещения, RVO/NRVO, STL и прочее). Если они берутся за софт, в котором критична предельная для железа скорость, и даже несколько лишних обращений к памяти уже ощущаются, то могут возникать неприятные сюрпризы.
Re[4]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 14:51
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Если мне не изменяет память, то разработчики STL максимально упарывались по производительности и потреблению памяти, чтобы работало и на утюгах.


Как раз на утюгах оно обычно работать не может. Это все-таки средства прикладного, а не системного программирования. Там нет предельной оптимизации — оно просто сделано так, чтобы работать в среднем лучше того же самого, вручную сделанного средним программистом.
Re[4]: Об эффективности виртуальных функций
От: andyp  
Дата: 05.08.24 14:52
Оценка:
Здравствуйте, пффф, Вы писали:

П>Ну, для set — это просто insert, для vector — это, скорее всего, push_back.

П>И хоть навставляйся хоть в set, хоть в vector через std::inserter

Инсертеры — тоже такая вещь, в которой не все прекрасно на мой взыскательный вкус . Этих итераторов для вставки три вида (back_insert_iterator, front_insert_iterator, insert_iterator), причем два из них по понятным причинам не будут работать с std::set. Параметром конструктора insert_iterator является итератор на позицию в контейнере для втыкания, который в случае std::set — просто хинт, а для последовательных контейнеров — нечто значимое.
Re[4]: Об эффективности виртуальных функций
От: andyp  
Дата: 05.08.24 14:55
Оценка:
Здравствуйте, пффф, Вы писали:

П>Ну, для set — это просто insert, для vector — это, скорее всего, push_back.


Дело не в том, что это будет технически, а в том что сам этот add имеет разный смысл для разных контейнеров. Вплоть до добавили "как-то куда-то". Я в самой такой абстракции мало смысла вижу
Re[4]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 05.08.24 15:00
Оценка:
Здравствуйте, karbofos42, Вы писали:

BFE>>Это потребует дополнительного расхода памяти размером в один указатель на объект, что противоречит известному принципу про платёж.

K>т.е. ТС не прав про гуманитариев, виртуальные методы создают большие накладные расходы и на них действительно имеет смысл экономить?
Евгений Музыченко пишет про скорость, а не про память.

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

BFE>>Впрочем, что мешает написать обёртку, которая будет принимать в конструкторе тип контейнера (или сам контейнер) и выставлять желаемый интерфейс? Такое можно написать за несколько часов без особого труда.

K>В итоге в проекте будет какой-то зоопарк, а накладных расходов ещё больше, чем было бы с виртуальными методами изначально.
Вот как напишете, такой зоопарк у вас и будет.

K>Хотя в плюсах наверно так принято, чтобы веселее было. Один интерфейс как в других языках — не интересно, а вот когда где-то vector, где-то QList или wxVector или ещё какой подобный класс — это весело и замечательно, особенно когда нужно из одного типа в другой данные гонять, т.к. у тебя есть vector, а нужный метод написан для QList.

Да, так принято и в этом нет ничего плохого.

BFE>>Однако, ICollection всё равно не получится сделать один на всех, ведь контейнеры шаблонные, а значит ICollection тоже будет шаблонным, т.е. ICollection<int> и ICollection<char> — это два разных типа.

K>так и пусть разные будут, лишь бы можно было в итоге написать без шаблонов и обёрток метод вида:
K>
K>void process(collection<int>& items)
K>{
K>  for (auto& value: items)
K>  {
K>    ...
K>  }
K>}
K>

K>и передать туда и std::vector<int> и std::set<int> и QList<int> (при условии конечно, что все они унаследуются от collection<int>)
Хмм... Есть у меня некоторые подозрения насчёт вашей квалификации...
Вот код:
void process(auto& items)
{
  for (auto& value: items)
  {
     std::cout << value << ' ';
  }
  std::cout << '\n';
}
//...
    std::vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);

    std::list<int> l;
    l.push_back(1);
    l.push_back(2);
    l.push_back(3);
    l.push_back(5);

    process(v);
    process(l);

Чем он вас не устраивает?
Зачем вам ICollection?

K>Или всё же такое наследование и последующие виртуальные вызовы добавят увеличение потребления памяти, существенно снизит скорость работы и в плюсах так не принято?

Что значит "принято"/"не принято"? C++ мультипарадигменный язык и стиль написания обычно зависит от квалификации программистов команды и их образования.
И каждый день — без права на ошибку...
Re[4]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 15:05
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>так и пусть разные будут, лишь бы можно было в итоге написать без шаблонов и обёрток метод вида


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

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

А если делать автоматические "подкапотные" средства, пусть и дающие малые накладные расходы для типовых прикладных задач, то при переходе к предельно нагруженным системам может оказаться, что накладные расходы стали слишком высоки, а избавиться от них невозможно, ибо они уже упрятаны под капот языка. И тогда остается или держать в языке аналогичные конструкции для низких уровней, или уходить на более низкоуровневый язык.
Re[7]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 15:12
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

П>>Или плюсовики, которые уделяют внимание вопросам производительности.


ЕМ>Среди профессиональных сишников преобладают те, кто пришел "снизу" — от железа и/или ассемблеров, ибо мало кто из чистых прикладников, привыкнув к современным ЯВУ, станет спускаться к C без крайней нужды.


Добрый десяток лет ковыряюсь с железом, так ни одного сишника и не увидел, одни плюсовики. В текущей конторе вообще по производительности сильно упарываются, и пишут всё на шаблонах, чтобы максимально всё оптимизировалось во время компиляции. И да, половина народу примерно лет 35ти возрастом. Это ещё не испорченные? Не слишком ли молоды для людей старой закалки?

Из сишников я вроде только одного знаю, если не ошибаюсь. Вроде тут на форуме, Pzz — чистый сишечник. Давай спросим его, откуда он пришел и насколько он упарывается по оптимизации?


ЕМ>Среди плюсовиков, пришедших в язык "сверху", изначально привыкших к "высокоуровневому" программированию, таких меньшинство.


Странно, у меня знакомый преподаёт в универе дисциплину что-то типа "Программирование микроконтроллеров", и делает это на плюсах


ЕМ>Система отбора, основанная на проверке знания стандартов, способствует тому, что человек умеет писать формально правильный код, но далеко не всегда видит, как именно по нему будет работать реальная машина.


Откуда ты знаешь про систему отбора?


ЕМ>Когда они делают на плюсах прикладной софт общего назначения, который работает заметно быстрее, чем у их коллег на Java/C#, у них может возникнуть ощущение, что они "уделяют внимание вопросам производительности", хотя на самом деле их спасают прежде всего готовые типовые оптимизации (семантика перемещения, RVO/NRVO, STL и прочее).


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


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


Такие сюрпризы любого могут ожидать
Re[5]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 15:12
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Что значит "принято"/"не принято"? C++ мультипарадигменный язык и стиль написания обычно зависит от квалификации программистов команды и их образования.


Тем не менее, оценки вроде "это не настоящий C++" можно встретить повсеместно.

Интересно, существуют подобные оценки для более других языков?