Общие лямбды и бинарный размер / раздувание кода - PullRequest
0 голосов
/ 13 сентября 2018

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

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 . Я хотел бы избежать этого, и мне интересно, могут ли лямбды помочь в борьбе с раздуванием кода шаблона. Это определено в стандарте или зависит от реализации компилятора?

1 Ответ

0 голосов
/ 13 сентября 2018

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

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

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

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

output of nm command

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

...