Подтвердить что ты не робот

Шаблонный класс больше, чем класс без шаблона, используя тот же тип?

Мне когда-то задавали трюк на собеседовании: у шаблонного класса больше памяти, чем у другого класса, который идентичен, но не шаблонизирован? Мой ответ был нет, но тот факт, что он задал вопрос, означает, что, вероятно, есть случай, когда есть. Или, он действительно хотел сокрушить меня. Каким будет случай, когда шаблонный класс будет занимать больше памяти?

4b9b3361

Ответ 1

Первое, что дает понять, в чем смысл вопроса. Если вопрос заключается в том, будут ли объекты типа более крупными (т.е. sizeof(T<int>) > sizeof(T_int)), тогда ответ будет отрицательным. Если вопрос касается бинарного следа самого приложения, в том числе кода для функций, то ответ заключается в том, что общий размер программы может фактически быть меньше в случае шаблона, поскольку будут использоваться только используемые функции-члены ( если явно не инстанцировано). Хотя в конце дня компоновщик может также отбросить неиспользуемые элементы из версии без шаблонов.

Существует общий термин: раздувание кода, которое используется для обозначения взрыва кода, сгенерированного шаблонами. Термин относится к тому факту, что каждое различное создание шаблона будет генерировать свои собственные функции, и это может привести к тому, что в исполняемом файле будет присутствовать больше функций, чем с меньшим набором функций без шаблона, для которых допускаются преобразования аргументов.

Рассмотрим возможный интерфейс для векторного шаблона:

template <typename T>
class Vector {
   template <typename U> void push_back(U u);
//....

Для каждого вызова push_back с другим типом аргумента будет создана новая функция, поэтому для Vector<int>::push_back('a') будет существовать функция, а другая для Vector<int>::push_back(1). Сравните это с интерфейсом std::vector, в котором функция-член не является шаблоном, а вызывающий выполняет преобразование типа.

Хотя это может быть источником больших исполняемых файлов, я не считаю, что это то, о чем просили. В частности, для шаблонизированного типа и эквивалентного типа без шаблона, созданного вручную для конкретного экземпляра, генерируемый код должен быть эквивалентным (игнорируя тот факт, что искаженные имена имеют тенденцию быть больше для шаблонов:))

Ответ 2

Ответ - НЕТ, насколько это касается памяти. Я имею в виду, что не обязательно брать больше памяти, хотя какой-то злой парень может написать шаблон шаблона, чтобы доказать свою точку зрения, что версия шаблона шаблона занимает больше памяти.

Однако исходный код шаблона класса может быть больше (или меньше, если на то пошло), чем версии non-template clas для определенного значения (ов) параметра (ов) типа.

template<typename T>
struct point_t
{
    T x, y, z;
};

struct point_int
{
    int x, y, z;
};

std::cout << (sizeof(point_int) == sizeof(point_t<int>)) << std::end;

Он напечатает true (или 1).

Обратите внимание только на то, что макет памяти point_int и point_t<int> будет таким же. Таким образом, вы можете даже сделать так:

point_t<int>  pt {10, 20, 30};

point_int  pi = *reinterpret_cast<point_int*>(&pt);

std::cout << "{" << pi.x <<"," << pi.y <<"," << pi.z << "}" << std::endl;

Он напечатает {10, 20, 30}.

Надеюсь, что это поможет.

Ответ 3

Шаблон заменяется реальными значениями во всех местах, которые он переопределяется во время компиляции. поэтому, если у вас есть класс шаблонов, скажите:

public List<T>
{
  public T* MyT;
  ...
}

и ваш код использует его с определенным типом: Список, чем то, что на самом деле происходит, что этот код используется:

public List<Point>
{
public Point *MyT;
....
}

Таким образом, он имеет сугубо такой же размер, как и любой другой класс без шаблона.