Здравствуйте, cppguard, Вы писали:
C>Заметил, что значительная часть нескольких последних стандартов иделяется этой части языка. Даже вот consteval появился. А насколько это реально нужно на практике? Точнее, у вас есть реальный пример, когда это было настолько нужно, что эквивалентоное единовременное вычисление на стадиции инициализации программы сильно проигрывает? Вообще существуют ещё языки, где есть что-то подобное?
Хотя rg45 и критиковал мою концепцию, однако все-же C++ разделятся на два разных подъязыка:
1. С++ времени компиляции.
2. C++ времени исполнения.
Это два разных языка, первый можно даже не использовать, при этом можно будет написать любую программу.
Первый ограничен — там нет возможности взаимодействия с системой, динамической памяти и пр. Но он довольно сложен, в чем-то даже более мозгодробилен, чем классический C++ времени исполнения.
Время компиляции допускает не так уж много конструкций. Интересные примеры:
Цикл, казалось бы:
constexpr int sumUpTo(int n)
{
int sum = 0;
for (int i = 1; i <= n; ++i)
sum += i;
return sum;
}
constexpr int sum = sumUpTo(10);
А вот if — не умеет, нужно только if constexpr:
template <typename T>
constexpr auto process(T value)
{
if constexpr (std::is_integral_v<T>)
return value * 2; // Вычисляется, если T — целое числоelse
return value / 2;
}
constexpr int result = process(5); // Результат 10
И даже
struct Point
{
int x, y;
constexpr Point(int x, int y) : x(x), y(y) {}
constexpr int distance() const { return x * x + y * y; }
};
constexpr Point p(3, 4);
constexpr int dist = p.distance();
Ваш вопрос мне так же интересен, но пока он для меня открыт. Имхо, какая-то ошибка концептуальная возникла, из-за чего пришлось добавлять подъязык в языке.
Самое парадоксальное, что при всей сложности этого подъязыка — он не позволяет полноценно сделать ORM, чтобы сделать что-то типа LINQ и оно само транслировалось в полноценные SQL-запросы. Только простые какие-то вещи можно сделать типа счетчика (и то будет тонна запутанного кода), но не реально полезные.
Здравствуйте, cppguard, Вы писали:
C>Заметил, что значительная часть нескольких последних стандартов иделяется этой части языка. Даже вот consteval появился. А насколько это реально нужно на практике?
Зависит от типа практики. Если у тебя какой ни будь одноуровневый домен-специфик, в рамках которого ты монотонно пилишь исключительно бизнесовую прикладуху без капитализации нарабатываемой кодовой базы — то все эти consteval нафик не нужны. А если капитализация таки имеет место то они становятся довольно востребованными.
C>Точнее, у вас есть реальный пример, когда это было настолько нужно, что эквивалентоное единовременное вычисление на стадиции инициализации программы сильно проигрывает?
Как то раз пришлось озаботиться собственным автоматом для разводки событий, аля boost::signals, но со своим блекджеком. И вот чтобы достигать zero-cost в максимальном количестве вариантов использования, применяется вся эте чертыхня с constexpr/шаблонами и прочей метапрограммирование-шнягой. То что получилось в итоге я бы оценил как "охренительно великолепно", удалось добиться быстродействия, сравнимого с наивными виртуальными вызовами с одной стороны и занчительного удобства для прикладного использования с другой. Тут можно посмотреть код
Здравствуйте, cppguard, Вы писали:
C>Заметил, что значительная часть нескольких последних стандартов иделяется этой части языка. Даже вот consteval появился. А насколько это реально нужно на практике? Точнее, у вас есть реальный пример, когда это было настолько нужно, что эквивалентоное единовременное вычисление на стадиции инициализации программы сильно проигрывает? Вообще существуют ещё языки, где есть что-то подобное?
В метапрограммировании — пользуемся почём зря.
Там не прямо вычисления-вычисления, но элементарно, параметризовать что-то в зависимости от размера данных или от булевых флажков со свойствами — помогает.
Доля таких constexpr в общей массе кода маленькая, но ненулевая.
Ещё одна вещь, где constexpr прямо очень нужен — статические константы.
struct foo {
foo(.....) {.....}
.....
};
struct bar {
constexpr bar(.....) {.....}
.....
};
/* static */const foo g_f; // ложится в секцию данных, выполняет конструктор перед main
/* static */const bar g_b; // ложится в секцию констант
Если ты не сталкивался с гонкой статических конструкторов, — ты счастливый человек, и у тебя все грабли впереди.
Здравствуйте, Shmj, Вы писали:
S>А вот if — не умеет, нужно только if constexpr:
S>
S>template <typename T>
S>constexpr auto process(T value)
S>{
S> if constexpr (std::is_integral_v<T>)
S> return value * 2; // Вычисляется, если T — целое число
S> else
S> return value / 2;
S>}
S>constexpr int result = process(5); // Результат 10
S>
Здравствуйте, cppguard, Вы писали:
C>А насколько это реально нужно на практике?
Изредка. Но когда нужно, тогда хз чем надежно заменить, особенно если итоговая система сборки тебе не подконтрольна и применимость внешней кодогенерации под вопросом (например, когда ты делаешь и распространяешь header-only библиотеку).
C>Точнее, у вас есть реальный пример, когда это было настолько нужно, что эквивалентоное единовременное вычисление на стадиции инициализации программы сильно проигрывает?
Маленький пример. Здесь constexpr нужен чтобы определить тип, который затем будет возвращаться методом make_c_string. Если у вас получится определить тип во время компиляции каким-то "единовременным вычислением на стадии инициализации", то constexpr вам вряд ли нужен.
ЗЫ. Любители чистого Си и старого-доброго Си-с-классами могут сказать, что это все баловство, и можно написать как диды писали:
Здравствуйте, rg45, Вы писали:
R>Ну вот и выходит, что все твои "концепции" находятся в области интерпретаций и субъективного восприятия. Которые к тому же часто заставляют путать тебя тёплое с мягким. Нет, конечно, ты можешь искать для себя лично какие-то собственные взгляды на предмет, если тебе так проще. Но навязывать свои "концепции" широкому кругу своего общения, наверное, не стоит. Если не хочешь сталкиваться с негативом на каждом шагу.
Да этот if constexpr ничего не меняет.
Вот взять код:
#include <iostream>
constexpr int multiply(int a, int b)
{
return a * b;
}
constexpr int square(int x)
{
return multiply(x, x);
}
int main()
{
constexpr int result = square(5);
std::cout << "Result: " << result << std::endl;
return 0;
}
Здесь square — функция времени компиляции. И она имеет право вызывать только функции времени компиляции. Как бы уже разделение, не совместимые вещи.
Шаблоны, концепты и пр. лабуда — это только и исключительно только времени компиляции.
Здравствуйте, so5team, Вы писали:
S>Да я вам даже больше скажу: class и struct, да что там, даже int или float -- это только и исключительно времени компиляции. Потом никаких классов и структур как run-time сущностей нет.
Есть разница где и когда происходит калькуляция, т.е. компьютинг — в момент компиляции на машине разработчика или в момент запуска на машине пользователя. Пример:
#include <iostream>
constexpr int fun1(int x)
{
return 100 / x;
}
int main()
{
constexpr int result = fun1(0);
std::cout << "Result: " << result << std::endl;
return 0;
}
— такой код даже не скомпилируется, вы не сможете сделать исполняемый файл.
А вот так:
#include <iostream>
int fun1(int x)
{
return 100 / x;
}
int main()
{
int result = fun1(0);
std::cout << "Result: " << result << std::endl;
return 0;
}
— вы уже сможете собрать исполняемый файл, дать его пользователю чтобы баг произошел на его стороне.
Разница есть?
Притом, когда попытаетесь собрать все конструкции, которые можно использовать в момент компиляции — окажется что их не так уж много. Но они самые мозгодробильные.
Заметил, что значительная часть нескольких последних стандартов иделяется этой части языка. Даже вот consteval появился. А насколько это реально нужно на практике? Точнее, у вас есть реальный пример, когда это было настолько нужно, что эквивалентоное единовременное вычисление на стадиции инициализации программы сильно проигрывает? Вообще существуют ещё языки, где есть что-то подобное?
Здравствуйте, cppguard, Вы писали:
C>Заметил, что значительная часть нескольких последних стандартов иделяется этой части языка. Даже вот consteval появился. А насколько это реально нужно на практике? Точнее, у вас есть реальный пример, когда это было настолько нужно, что эквивалентоное единовременное вычисление на стадиции инициализации программы сильно проигрывает? Вообще существуют ещё языки, где есть что-то подобное?
Баловство всё. Вычисления можно делать еще до компиляции и генерировать код уже с правильными константами.
Здравствуйте, kov_serg, Вы писали:
_>Баловство всё. Вычисления можно делать еще до компиляции и генерировать код уже с правильными константами.
Дык вручную может быть не удобно, притом что результат может зависеть от платформы. Вот чел. сделал счетчик времени компиляции — http://rsdn.org/forum/cpp/8858730.flat
Здравствуйте, so5team, Вы писали:
S>Иногда лучше жевать, чем говорить (c)
Да, извиняюсь, работает и без constexpr if. В свое оправдание могу сказать что не приходилось вообще использовать сложные конструкции во время компиляции и пока не особо вижу в них смысл.
Здравствуйте, Shmj, Вы писали:
S>Да, извиняюсь, работает и без constexpr if. В свое оправдание могу сказать что не приходилось вообще использовать сложные конструкции во время компиляции и пока не особо вижу в них смысл.
Ну вот и выходит, что все твои "концепции" находятся в области интерпретаций и субъективного восприятия. Которые к тому же часто заставляют путать тебя тёплое с мягким. Нет, конечно, ты можешь искать для себя лично какие-то собственные взгляды на предмет, если тебе так проще. Но навязывать свои "концепции" широкому кругу своего общения, наверное, не стоит. Если не хочешь сталкиваться с негативом на каждом шагу.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, Shmj, Вы писали:
S>Здесь square — функция времени компиляции. И она имеет право вызывать только функции времени компиляции. Как бы уже разделение, не совместимые вещи.
Здравствуйте, Shmj, Вы писали:
S>Здесь square — функция времени компиляции. И она имеет право вызывать только функции времени компиляции. Как бы уже разделение, не совместимые вещи.
Примеров по схеме "вот так можно, а вот так нельзя" можно придумать громадное количество. Но это ж всё не поводы для разбиения на "подъязыки".
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, Shmj, Вы писали:
S>Шаблоны, концепты и пр. лабуда — это только и исключительно только времени компиляции.
Да я вам даже больше скажу: class и struct, да что там, даже int или float -- это только и исключительно времени компиляции. Потом никаких классов и структур как run-time сущностей нет.
Здравствуйте, cppguard, Вы писали:
C>насколько это реально нужно на практике?
В общем случае constexpr/consteval полезны хотя бы для того, чтобы явно указать "всё необходимое для вычисления должно быть известно на этапе компиляции, иначе у нас что-то не так с концепцией". Просто как одна из форм static assert.
C>у вас есть реальный пример, когда это было настолько нужно, что эквивалентоное единовременное вычисление на стадиции инициализации программы сильно проигрывает?
Чтоб прям проигрывало, нужны очень жесткие требования по ресурсам. В каком-нибудь мелком МК перенос вычисления в рантайм запросто может привести к невлезанию прошивки в память, а на сколько-нибудь серьезных платформах это чаще всего незаметно.
Здравствуйте, cppguard, Вы писали:
C>Заметил, что значительная часть нескольких последних стандартов иделяется этой части языка. Даже вот consteval появился. А насколько это реально нужно на практике? Точнее, у вас есть реальный пример, когда это было настолько нужно, что эквивалентоное единовременное вычисление на стадиции инициализации программы сильно проигрывает? Вообще существуют ещё языки, где есть что-то подобное?
Не стоит смотреть на вычисления времени компиляция только лишь как на средство оптимизации быстродействия. Константы времени компиляции могут участвовать в образовании типов и определении концептов, участвовать в overload resolution и пр. Да и сами константы сейчас это уже не только числа, но и объекты классов, позволяющие эффективно выстраивать системы типов со статическим полиморфизмом, расскладывать сложные задачи на подзадачи и стратегии, обеспечивать возможность определять моки для юнит-тестов и много чего еще.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, Shmj, Вы писали:
S>Здравствуйте, kov_serg, Вы писали:
_>>Баловство всё. Вычисления можно делать еще до компиляции и генерировать код уже с правильными константами.
S>Дык вручную может быть не удобно, притом что результат может зависеть от платформы. Вот чел. сделал счетчик времени компиляции — http://rsdn.org/forum/cpp/8858730.flat
Здравствуйте, cppguard, Вы писали:
C>Здравствуйте, kov_serg, Вы писали:
_>>Баловство всё. Вычисления можно делать еще до компиляции и генерировать код уже с правильными константами.
C>Так вот и я клоню в эту сторону. Кодогенерация была задолго до constexpr и хорошо работала.
Именно. Вот следовало бы добавить препроцессор типа lua до этапа компиляции в стандарт и не канифолить мозг.
Скрипты могут сделать на порядок больше и удобнее чем извращаться с метапрограммирование на недо-шаблонах.
Здравствуйте, Shmj, Вы писали:
S>>Да я вам даже больше скажу: class и struct, да что там, даже int или float -- это только и исключительно времени компиляции. Потом никаких классов и структур как run-time сущностей нет.
S>Есть разница где и когда происходит калькуляция, т.е. компьютинг — в момент компиляции на машине разработчика или в момент запуска на машине пользователя.
Есть разница где и когда происходит определение типов сущностей -- вот в compile-time мы определяем типы и компилятор обрабатывает наши декларации class и struct, а в run-time, на машине пользователя, мы не можем определить в коде новый class.
A-A-A! Два разных языка! Какой ужос! Мы все умрем!
Здравствуйте, rg45, Вы писали:
R>Вот так нельзя сделать исполняемый файл: R>А вот так можно:
R>Здесь тоже два разных языка?
Ключевое слово — калькуляция. Язык нужен чтобы что-то вычислять — иначе смысла нет.
Так вот — C++ умеет вычислять в двух режимах: обычный режим в момент исполнения на компе пользователя. И второй режим вычисления — в момент компиляции.
Тот же голый С если и может что вычислять в момент сборки, то достаточно примитивные вещи — как то примитивные арифметические операции. У C++ возможности намного шире.
Ну можно еще иначе назвать: конструкции языка C++, которые поддерживают вычисления в момент компиляции. Т.е. грубо говоря то, что можно написать внутри функции constexpr (которая используется в режиме компиляции).
#include <iostream>
constexpr int fun1(int x)
{
// Какие конструкции мы можем использовать тут?return 100 / x;
}
int main()
{
constexpr int result = fun1(0);
std::cout << "Result: " << result << std::endl;
return 0;
}
— а конструкций не так уж много, получается. Ни выделение памяти с помощью new, ни reinterpret_cast/dynamic_cast/const_cast. Т.е. совсем другой ограниченный язык, совсем другие возможности. Ну да, во многом похож на C++.
Здравствуйте, Shmj, Вы писали:
S>Ключевое слово — калькуляция. Язык нужен чтобы что-то вычислять — иначе смысла нет.
Это кто так постановил?
И что ты понимаешь под калькуляцией? Давай-ка вначале дадим определения, потом будем манипулировать, хорошо?
Например, из чего должно быть понятно, что операции с числами относятся к "калькуляциям", а операции с типами — нет? И что там с объектами составных типов, которые также могут создаваться во время компиляции — это подпадает под понятие "калькуляции", или нет?
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, Shmj, Вы писали:
S>Ну можно еще иначе назвать: конструкции языка C++, которые поддерживают вычисления в момент компиляции. Т.е. грубо говоря то, что можно написать внутри функции constexpr (которая используется в режиме компиляции).
Здравствуйте, rg45, Вы писали:
S>>Ключевое слово — калькуляция. Язык нужен чтобы что-то вычислять — иначе смысла нет. R>Это кто так постановил?
В этом смысл компьютера — производить вычисления, т.е. преобразование входящих данных в исходящие.
R>И что ты понимаешь под калькуляцией? Давай-ка вначале дадим определения, потом будем манипулировать, хорошо?
Преобразование данных по неким правилам.
R>Например, из чего должно быть понятно, что операции с числами относятся к "калькуляциям", а операции с типами — нет? И что там с объектами составных типов, которые также могут создаваться во время компиляции — это подпадает под понятие "калькуляции", или нет?
Создание типа — это лишь подготовка к калькуляции. Тип может упростить калькуляцию, когда мы некий набор данных рассматриваем как единое целое.
тебе говорили про struct, class, int, float — всё это можно написать внутри функции constexpr. Так с чем ты не согласен?
Совершенно верно — в C++ возможности калькуляции в компил-тайм режиме — огромны. Но все же во многом ограничены — не все операторы работают, нет доступа к системным функциям.
Здравствуйте, Shmj, Вы писали:
S>В этом смысл компьютера — производить вычисления, т.е. преобразование входящих данных в исходящие.
Ну то есть, вместо того, чтобы пояснить тезис, ты просто его повторил. Ну ОК, смотрим дальше.
S>Преобразование данных по неким правилам.
Поподробнее пожалуйста. Получение размера кортежа можно считать "преобразованием данных по неким правилам"?
S>Создание типа — это лишь подготовка к калькуляции. Тип может упростить калькуляцию, когда мы некий набор данных рассматриваем как единое целое.
Ну то есть, ты продолжаешь манипулировать термином, так и не предоставив его определения. Почему-то я не удивлён.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, Shmj, Вы писали:
S>Совершенно верно — в C++ возможности калькуляции в компил-тайм режиме — огромны. Но все же во многом ограничены — не все операторы работают, нет доступа к системным функциям.
И? Как из этого следует существование двух языков? И почему только двух?
Типа, первый язык — это всё то, что напоминает тебе твой любимый "приятный" язык, а второй — это всё остальное?
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
R>И? Как из этого следует существование двух языков? И почему только двух? R>Типа, первый язык — это всё то, что напоминает тебе твой любимый "приятный" язык, а второй — это всё остальное?
То что при вычислениях разный список слов — делает языки разными. Диалекты, если хотите.
Здравствуйте, rg45, Вы писали:
R>А как я должен был понять, что под "калькуляциями" ты имеешь в виду "вычисление" из википедии. R>Ну, хорошо. И как из этого определения выводится, что С++ заключает в себе два разных языка? Можно посмотреть всю цепочку рассуждений целиком?
C++ можно использовать для вычислений в двух режимах:
1. В момент компиляции. На машине разработчика/билд-сервера.
2. В момент исполнения. Уже на машине конечного пользователя.
Для сравнения возьмите более православный C. Какие вычисления вы там сможете сделать в режиме компиляции и какие конструкции доступны? Ну разве что const int c = a + b; Макросы не беру, с ними отдельная история.
C++ же значительно расширяет возможности вычислений при компиляции, добавляет новые конструкции и делает доступными часть конструкций из режима исполнения (но не все).
Здравствуйте, Shmj, Вы писали:
S>C++ можно использовать для вычислений в двух режимах:
S>1. В момент компиляции. На машине разработчика/билд-сервера. S>2. В момент исполнения. Уже на машине конечного пользователя.
Ну, это для меня что-то новое. А можно поподробнее, каким образом С++ участвует в моменте исполнения на машине конечного пользователя?
А то в стандарте языка врут, что последняя фаза работы C++ это:
All external entity references are resolved. Library components are linked to satisfy external references to entities not defined in the current translation. All such translator output is collected into a program image which contains information needed for execution in its execution environment.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
S>>1. В момент компиляции. На машине разработчика/билд-сервера. S>>2. В момент исполнения. Уже на машине конечного пользователя.
R>Ну, это для меня что-то новое. А можно поподробнее, каким образом С++ участвует в моменте исполнения на машине конечного пользователя?
Придираетесь к словам.
Ясно же что речь о тех инструкциях машинного кода, которые порождает C++. Часть инструкций им порождаемых исполняется сразу в момент компиляции. А другая часть инструкций будет выполнена лишь потом, когда бинарник будет запущен на машине пользователя.
Так вот та часть языка, которая умеет порождать выполняющиеся в момент компиляции инструкции — отличается от другой части языка, которая порождает инструкции для времени выполнения.
Здравствуйте, Shmj, Вы писали:
S>>>1. В момент компиляции. На машине разработчика/билд-сервера. S>>>2. В момент исполнения. Уже на машине конечного пользователя.
R>>Ну, это для меня что-то новое. А можно поподробнее, каким образом С++ участвует в моменте исполнения на машине конечного пользователя?
S>Придираетесь к словам.
А, то есть, это я виноват, что ты не можешь изложить мысль? Ну, ОК.
S>Ясно же что речь о тех инструкциях машинного кода, которые порождает C++. Часть инструкций им порождаемых исполняется сразу в момент компиляции. А другая часть инструкций будет выполнена лишь потом, когда бинарник будет запущен на машине пользователя.
Да. И где тут два языка С++? Ну да, С++ порождает очень разнообразный код. И?
S>Так вот та часть языка, которая умеет порождать выполняющиеся в момент компиляции инструкции — отличается от другой части языка, которая порождает инструкции для времени выполнения.
Да. А та часть языка, которая умеет обрабатывать конструкторы, отличается от той части языка, которая умеет обрабадывать деструкторы. А Волга впадает в Каспийское море. Так а где два языка С++?
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
S>>Ясно же что речь о тех инструкциях машинного кода, которые порождает C++. Часть инструкций им порождаемых исполняется сразу в момент компиляции. А другая часть инструкций будет выполнена лишь потом, когда бинарник будет запущен на машине пользователя.
R>Да. И где тут два языка С++? Ну да, С++ порождает очень разнообразный код. И?
Критерий ГДЕ и КОГДА исполняется код — очень важен.
То ли на машине разработчика и сразу, в момент компиляции. Это одно. Совсем другое дело когда порожденные инструкции исполняются при исполнении. Это очень четкий критерий.
Обычно языки не умеют ничего выполнять в момент компиляции/сборки. Ну как, примитивные некие конструкции арифметические и не более того, что бы значение константы писать более понятным образом (как то 24*7). С++ же в этом отношении отличается от других языков и весьма сильно — тут возможность компил-тайма огромны.
Если вы попытаетесь составить табличку что можно в компил-тайм а чего нельзя — поймете что это совсем другой язык.
Здравствуйте, Shmj, Вы писали:
S>Критерий ГДЕ и КОГДА исполняется код — очень важен.
Важен для кого/чего? Обоснуй?
S>То ли на машине разработчика и сразу, в момент компиляции. Это одно. Совсем другое дело когда порожденные инструкции исполняются при исполнении. Это очень четкий критерий.
Критерий чего?
S>Обычно языки не умеют ничего выполнять в момент компиляции/сборки.
Ну, это уже от языков зависит. В C++ эти возможности были изначально (sizeof, например).
S>Ну как, примитивные некие конструкции арифметические и не более того, что бы значение константы писать более понятным образом (как то 24*7). С++ же в этом отношении отличается от других языков и весьма сильно — тут возможность компил-тайма огромны.
Ну, допустим, С++ сильно отличается от других языков. Откуда берется два С++ — это по-прежнему не понятно.
S>Если вы попытаетесь составить табличку что можно в компил-тайм а чего нельзя — поймете что это совсем другой язык.
Я думаю, что уж как-нибудь получше тебя представляю, что можно в компайл-тайм, а чего нельзя. Но это по-прежнему меня не убеждает в существовании двух языков С++.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, Shmj, Вы писали: S>Критерий ГДЕ и КОГДА исполняется код — очень важен.
Давай попробуем идти от частного к общему. Рассмотрим такой несложный пример:
#include <iostream>
int foo(int x) { return x * 10; }
int bar(int x) { return x * 100; }
int main()
{
int value = foo(3) + bar(5);
std::cout << value << std::endl;
}
Согласно твоим критериям, на каком языке написана данная программа?
Спойлер
В зависимости от опций компиляции, значение value может вычисляться как в компайл- так и в ран-тайме. И согласно твоим критериям, мы не можем определить, на каком языке написана программа, пока не изучим сгенерированный код, так получается?
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, vopl, Вы писали:
V>без капитализации нарабатываемой кодовой базы
Что такое "капитализация нарабатываемой базы"? Получение выгоды раз за разом из единожды написанного кода?
V>Как то раз пришлось озаботиться собственным автоматом для разводки событий, аля boost::signals, но со своим блекджеком. И вот чтобы достигать zero-cost в максимальном количестве вариантов использования, применяется вся эте чертыхня с constexpr/шаблонами и прочей метапрограммирование-шнягой. То что получилось в итоге я бы оценил как "охренительно великолепно", удалось добиться быстродействия, сравнимого с наивными виртуальными вызовами с одной стороны и занчительного удобства для прикладного использования с другой. Тут можно посмотреть код
Выглядит сложно, но можно в двух словах о том, что там действительно происходит? Почему, скажем, на Java это должно работать медленее (без учёта времени на JIT и сборку мусора)?
Здравствуйте, cppguard, Вы писали:
C>Здравствуйте, vopl, Вы писали:
V>>без капитализации нарабатываемой кодовой базы C>Что такое "капитализация нарабатываемой базы"? Получение выгоды раз за разом из единожды написанного кода?
Да. К такому капитальному коду практически всегда относятся инструменты, которые сами по себе являются средствами производства — библиотеки/фреймворки, подобное. Почему в таком коде находит применение сабж — потому что пользователем данного кода является сам инженер, и его варианты использования лежат внутри инструмента а не снаружи, вот ему и требуются всякие "чтоб было посчитано в компайлтайме", "чтоб функцию с таким типом аргумента можно было вызвать а нестаким нет", "чтоб не писать ручками 100500 бойлерплейта а оно само чтобы сгенерировалось"...
V>>Как то раз пришлось озаботиться собственным автоматом для разводки событий, аля boost::signals, но со своим блекджеком. И вот чтобы достигать zero-cost в максимальном количестве вариантов использования, применяется вся эте чертыхня с constexpr/шаблонами и прочей метапрограммирование-шнягой. То что получилось в итоге я бы оценил как "охренительно великолепно", удалось добиться быстродействия, сравнимого с наивными виртуальными вызовами с одной стороны и занчительного удобства для прикладного использования с другой. Тут можно посмотреть код
C>Выглядит сложно, но можно в двух словах о том, что там действительно происходит? Почему, скажем, на Java это должно работать медленее (без учёта времени на JIT и сборку мусора)?
В двух словах — имеет место некая система, сложенная из множества подсистем (то есть сложная), полностью выполняющая свое предназначение (функционально полная) с хорошим уровнем быстродействия/удобства использования (эффективная), при этом она не разваливается под тяжестью собственной сложности (органичная), и как следствие, вполне устойчива при использовании/доработке (робастная в аспекте жизненной динамики). Всех этих показателей вряд ли можно достичь без использования метапрограмминга (constexpr, шаблоны, ...)
На Яве это будет работать не менее замечательно, при условии что в стандартной бибилиотеке Явы найдутся средства чтобы сделать это именно так. Если задача прецедентная — то такие средства с большой вероятностю там таки найдутся, и все будет хорошо. Но если задача не вполне прецедентная (со своим блекджеком), то таких средств в Яве не найдется, придется лепить костылями из доступных средств, вследствие чего быстродействие/удобство и прочие тактико-технические характеристики просядут. Собственно, в этом и есть сила C++, в нем ты можешь сам себе построить "средства производства" чтобы потом на их основе строить прикладуху как второй уровень. И вся система будет органична/эффективна. В Яве же средства производства поставляются центральным вендором, что в некотором смысле ограничивает разработчика.
Здравствуйте, rg45, Вы писали:
R>Согласно твоим критериям, на каком языке написана данная программа?
Компил-тайм язык отличается тем что:
1. Не позволяет обращаться к изменяемым глобальным переменным (включая constinit) а так же не позволяет иметь static-переменные внутри функции, т.е. как бы запрет на состояние между вызовами функций. Сюда же запрет на const_cast.
2. Не позволяет динамически выделять память, использовать указатель на базовый объект, полноценно работать с полиморфизмом и вирт. функциями. Запрет на dynamic_cast.
3. Почему то запрет на reinterpret_cast.
4. Запрещены вызовы системных функций — результат вычисления можно поместить либо в constexpr/constinit переменную либо использовать для static_assert. Все — больше никакого внешнего воздействия с миром.
Вроде мелочи, но это сокращает возможности языка до неузнаваемости. Даже если вы попытаетесь сделать банальный счетчик вызовов функции (а оказывается это можно сделать
1. Нет обращения к изменяемым глобальным переменным, нет статических переменных внутри функции.
2. Нет динамического выделения памяти.
3. Нет reinterpret_cast.
4. Нет вызова системных функций.
Здравствуйте, Shmj, Вы писали:
S>Поскольку:
S>1. Нет обращения к изменяемым глобальным переменным, нет статических переменных внутри функции. S>2. Нет динамического выделения памяти. S>3. Нет reinterpret_cast. S>4. Нет вызова системных функций.
S>- то на компил-тайм языке.
Здравствуйте, rg45, Вы писали:
R>Да ты не спеши за компилятор говорить. Ты актуализируй сперва все свои критерии. А то у тебя получается, что ты правой пишешь, левой зачёркиваешь.
Оно связано.
Для компил-тайм сильно ограничили язык, фактически до неузнаваемости. Хотя в теории могли бы и снять ограничения, наверное.
Даже написать тот же счетчик для компил-тайма — это отдельный вид мастерства.
S>Оно связано. S>Для компил-тайм сильно ограничили язык, фактически до неузнаваемости. Хотя в теории могли бы и снять ограничения, наверное. S>Даже написать тот же счетчик для компил-тайма — это отдельный вид мастерства.
Ну вот, опять какие-то общие слова и никакой конкретики. Я от тебя устал, если честно.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, Shmj, Вы писали:
S>Оно связано. S>Для компил-тайм сильно ограничили язык, фактически до неузнаваемости. Хотя в теории могли бы и снять ограничения, наверное. S>Даже написать тот же счетчик для компил-тайма — это отдельный вид мастерства.
Я тебе, правда, очень признателен за то, что ты вписался за меня, когда меня отправили в бан. В то же время, у меня к тебе огромная просьба: не заваливай этот форум своими философскими "концепциями". Пускай технический форум остается чисто техническим. Ладно?
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
R>Я тебе, правда, очень признателен за то, что ты вписался за меня, когда меня отправили в бан. В то же время, у меня к тебе огромная просьба: не заваливай этот форум своими философскими "концепциями". Пускай технический форум остается чисто техническим. Ладно?
Так эта тема то не мной создана и изначально холиварная. Вопроса технического никакого нет. Чел. просто не согласен с философией — максимум вопрос тяняет на Философию программирования. Ну раз не удалили — то почему бы не обсудить?
И второе. Форумное членство так сказать — не особо важно. Важно другое — как в мелком люди поступают — так поступят и в крупном. Т.е. если у вас в жизни что-то плохое случится, то поддержат только такие люди как я. Кто-то проигнорит а кто-то еще и камень кинет.
под свои нужды переделал один известный, но мало использоваемый regex либ
что бы конструирование стейт машины было на этапе компайл тайм
собственно можно поискать по форуму
я просил апать баг репорты для clang что бы пофиксили consteval
в чем суть
regex r("(.*?)(end)+(.*?)$"); //конструирование стейт машины
std::string input;
r.match(input);
std::string a = r[1];
std::string b = r[2];
после компиляции, все строки регекспа видны в бинаре
ксорить итд как то не красиво
а по итогу сама строка переводиться каждый раз во внутреннее состояние
надеяться на constexpr не приходиться
лезть потом в бинарь и проверять
а сбилдилось ли оно в бинарный массив состояний или осталось строкой, слишком накладно
а consteval это делает наверняка
вообщем то сейчас многие начнут возражать
агааааа есть же regex компаил тайм от Даши Гуськовой(Hana Dusikova)
ну он мне не зашел
Здравствуйте, Shmj, Вы писали:
S>Так эта тема то не мной создана и изначально холиварная. Вопроса технического никакого нет. Чел. просто не согласен с философией — максимум вопрос тяняет на Философию программирования. Ну раз не удалили — то почему бы не обсудить?
Ну, я не только про эту тему говорю, но и вообще. Ты же не впервые развиваешь эту и подобные ей темы. Да и в этот холивар совсем не обязательно было подливать собственного керосина.
S>Важно другое — как в мелком люди поступают — так поступят и в крупном.
В этом я не раз убеждался.
--
Справедливость выше закона. А человечность выше справедливости.