Общие лямбды и двоичный размер / раздувание кода

Какая разница в полученном двоичном файле, когда мы сравниваем этот код:

struct S {
    template<typename... Args>
    void operator()(Args... args) { /* ... */ }
};

// And then inside some block:
S s;
s(42);
s(3.14, "Hi!");
s("Hi!", 3.14);

... к этому коду:

const auto l = [](auto... args) { /* ... */ };

// And then inside some block:
l(42);
l(3.14, "Hi!");
l("Hi!", 3.14);

Насколько я понимаю, код struct создает 3 экземпляра шаблона для operator(), все из которых отображаются в виде символов в двоичном файле. А лямбда? Компилятор создает объект, аналогичный s. Но если это безымянный тип класса, создает ли он символы в двоичном файле?

Мотивация: Я использовал библиотеку с большим количеством шаблонов, в которой мне пришлось включить / bigobj. Я бы хотел этого избежать, и мне интересно, могут ли лямбды помочь против раздувания кода шаблона. Это определено в стандарте или зависит от реализации компилятора?

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

Guillaume Racicot 13.09.2018 01:26

Попробуйте поместить структуру в безымянное пространство имен.

Kerrek SB 13.09.2018 01:33

Посмотрите на вывод вашего компилятора и найдите свой актуальная проблема. Шаблоны и т. д. Являются синтаксическим сахаром. «Раздутый код» сейчас не так актуален, как 20 лет назад, а хранение стоит намного меньше, чем время разработчика. Какова ваша настоящая цель здесь? Ваши примеры делают то же самое. ЕСЛИ он компилируется, это потому, что компилятор будет генерировать разные версии для auto, как и для шаблонов. auto не предоставляет динамическая типизация. Это все еще статически типизированный язык, и вам нужны разные версии для разных типов. Шаблоны, другая магия компилятора - не имеет значения.

3Dave 13.09.2018 01:34

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

crazypeter 13.09.2018 01:46

@crazypeter Это особенность общих лямбд.

François Andrieux 13.09.2018 02:14

@ 3Dave Как я уже писал, моя «настоящая цель» - избегать / bigobj. Можете ли вы дать мне ссылку, чтобы доказать, что выходные данные компилятора (за исключением, возможно, имен символов) точно такие же в двух примерах? Мой вопрос: поскольку лямбда создает безымянный тип класса, создает ли он символы в двоичном файле?

basteln 13.09.2018 09:16
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
268
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, к сожалению, лямбда не может помочь вам решить проблему раздувания кода. Для вашего примера, такого как struct S, компилятор также создаст три разных оператора () для лямбда.

Чтобы подтвердить свою точку зрения, я скомпилировал следующую программу с g ++ 8.1.0 в Linux.

int main()
{
    const auto l = [](auto... args) { /* ... */ };
    l(42);
    l(3.14, "Hi!");
    l("Hi!", 3.14);
}

а затем используйте команду нм для просмотра двоичного файла, результат будет следующим:

output of nm command

Нетрудно заметить, что последние три строки - это символы трех операторов (). Итак, в этом случае лямбда и структура S принципиально не отличаются.

Спасибо! Хорошо знать.

basteln 13.09.2018 18:08

Другие вопросы по теме