Sizeof типа std :: function <void (int &)>

Что за магия творит std::function из C++ 11, чем его 9X_cxx sizeof = 32? Если бы я сохранил ссылку на функцию в 9X_gcc виде указателя, это стоило бы всего 8 bytes (на 9X_c++ 64-битной машине).

26
5

  • @GManNickG Да, это то, о чем я прошу, то есть внутренности. Эти файлы STL практически н ...
2
Общее количество ответов: 2

Ответ #1

Ответ на вопрос: Sizeof типа std :: function <void (int &)>

Для std::function это интересный компромисс между размером 9X_cxx объекта и распределением: для небольших 9X_c++11 функциональных объектов желательно избегать 9X_cpp выделения. С другой стороны, это увеличивает 9X_c++0x размер объекта. Чтобы оптимизация небольших 9X_c++11 функций была полезной и не приводила к накладным 9X_cpp расходам при фактическом вызове объекта, размер 9X_gcc объекта должен составлять как минимум два 9X_c++0x указателя плюс некоторая память для хранения 9X_c++11 простых функциональных объектов. Кажется, что 9X_stl размер 32 байта именно такой (в системе, где 9X_c++11 sizeof(T*) равно 8).

То есть внутри объекта std::function хранится 9X_cpp иерархия наследования: базовый класс предоставляет 9X_c++11 интерфейс для вызова, делегируя его производному 9X_cpp по шаблону, который реализует интерфейс 9X_c++0x вызова (плюс, возможно, некоторые функции 9X_c++0x clone()). В реализации, оптимизированной для размера, функциональный 9X_stl-containers объект будет просто хранить указатель на 9X_cxx базу, но, чтобы избежать выделения, он выделит 9X_stl-containers некоторую внутреннюю память для выделения 9X_cpp всего объекта и указывает на этот объект 9X_stl-containers (внутренний указатель избегает условия при 9X_cpp фактическом вызове объект функции). Память, необходимая 9X_c++0x для объекта, представляет собой указатель 9X_gcc виртуальной функции плюс любые данные для 9X_stl-containers фактического функционального объекта, которым 9X_gcc инициализируется объект std::function. Чтобы приспособить 9X_cpp функции-члены к их объекту, кажется, что 9X_c++0x еще два слова достаточно мало.

17
1

  • @LightnessRacesinOrbit: один указатель, указывающий на базу, и указатель виртуальной функции. Плюс данные для фактического фун ...

Ответ #2

Ответ на вопрос: Sizeof типа std :: function <void (int &)>

std::function действительно волшебный, поскольку он может 9X_c++0x быть построен из любого вызываемого объекта! Он 9X_c++ с радостью сохранит для вас любое количество 9X_gcc состояний, даже если на поверхности вы сохраните 9X_c++0x жалкую подпись void(int&).

За эту магию, безусловно, есть 9X_stl-containers своя цена, которая обычно использует какое-то 9X_c++ стирание типа (например, динамическое распределение 9X_c++11 и виртуальную отправку) внутри компании. Детали 9X_c++0x различаются, но получаемые в результате 9X_stl-containers объекты определенно «тяжелые» - поэтому 9X_stl их следует избегать в пользу auto и шаблонов, когда 9X_cpp это возможно!

8
2

  • @Martin Если у меня есть `struct big {void operator()() {}; пустышка [N]; }; `тогда я могу хранить произвольное количество байтов в` std : ...