Какая разница в полученном двоичном файле, когда мы сравниваем этот код:
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. Я бы хотел этого избежать, и мне интересно, могут ли лямбды помочь против раздувания кода шаблона. Это определено в стандарте или зависит от реализации компилятора?
Попробуйте поместить структуру в безымянное пространство имен.
Посмотрите на вывод вашего компилятора и найдите свой актуальная проблема. Шаблоны и т. д. Являются синтаксическим сахаром. «Раздутый код» сейчас не так актуален, как 20 лет назад, а хранение стоит намного меньше, чем время разработчика. Какова ваша настоящая цель здесь? Ваши примеры делают то же самое. ЕСЛИ он компилируется, это потому, что компилятор будет генерировать разные версии для auto
, как и для шаблонов. auto
не предоставляет динамическая типизация. Это все еще статически типизированный язык, и вам нужны разные версии для разных типов. Шаблоны, другая магия компилятора - не имеет значения.
Я предполагаю, что последний пример даже не компилируется, потому что аргументы имеют разные типы в разных вызовах?
@crazypeter Это особенность общих лямбд.
@ 3Dave Как я уже писал, моя «настоящая цель» - избегать / bigobj. Можете ли вы дать мне ссылку, чтобы доказать, что выходные данные компилятора (за исключением, возможно, имен символов) точно такие же в двух примерах? Мой вопрос: поскольку лямбда создает безымянный тип класса, создает ли он символы в двоичном файле?
Я думаю, к сожалению, лямбда не может помочь вам решить проблему раздувания кода. Для вашего примера, такого как struct S, компилятор также создаст три разных оператора () для лямбда.
Чтобы подтвердить свою точку зрения, я скомпилировал следующую программу с g ++ 8.1.0 в Linux.
int main()
{
const auto l = [](auto... args) { /* ... */ };
l(42);
l(3.14, "Hi!");
l("Hi!", 3.14);
}
а затем используйте команду нм для просмотра двоичного файла, результат будет следующим:
Нетрудно заметить, что последние три строки - это символы трех операторов (). Итак, в этом случае лямбда и структура S принципиально не отличаются.
Спасибо! Хорошо знать.
В этом случае действительно поможет встраивание, удалив символы лямбда-выражений.