Шаблоны C ++ и создание экземпляров объектного кода - PullRequest
0 голосов
/ 06 августа 2010

С этим вопросом я бы хотел лучше понять, как работает система шаблонов C ++ в отношении этого вопроса .

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

В заголовочном файле something.h наш класс должен быть определен следующим образом:

template <typename T>
class Something
{
    public:
        void setElement (T &elem) {
            element = elem;
        }
        T getElement () {
            return element;
        }
    private:
        T element;
};

Теперь давайте предположим, что разделить определение источника и класса:

Следующее определение класса будет записано в something.h:

template <typename T>
class Something
{
    public:
        void setElement (T &elem);
        T getElement ();
    private:
        T element;
};

Пока в something.cpp будут написаны следующие методы:

#include "something.h"

template <typename T>
void Something<T>::setElement (T &elem)
{
    element = elem;
}

template <typename T>
T Something<T>::getElement ()
{
    return element;
}

Если мы не объявим некоторые экземпляры определенного типа внутри something.cpp, если мы скомпилируем его как объектный файл, мы не получим никакого текстового раздела внутри него:

dacav@mithril:<tmp>$ g++ something.cpp  -c
dacav@mithril:<tmp>$ objdump -D something.o 

something.o:     file format elf64-x86-64


Disassembly of section .comment:

0000000000000000 <.comment>:
   0:   00 47 43                add    %al,0x43(%rdi)
   3:   43 3a 20                rex.XB cmp    (%r8),%spl
...
...
  20:   34 2e                   xor    $0x2e,%al
  22:   31 00                   xor    %eax,(%rax)
dacav@mithril:<tmp>$

Как показывает Мартин Йорк , мы можем заставить компилятор генерировать код для некоторых конкретных типов данных, чтобы контролировать, какие типы можно использовать, а какие нет. Но что, если мы не хотим никаких ограничений?

Ответы [ 2 ]

2 голосов
/ 06 августа 2010

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

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

something.h

// Just the declaration

template<typename T>
class Something {
  void foo();
};

// include the header file with the definitons
#include "something.impl.h"

something.impl.h

// Put definitions here

template<typename T>
void Something<T>::foo() {
}
1 голос
/ 06 августа 2010

Короче, ты чучела. Стандарт определил ключевое слово «export», которое должно было экспортировать шаблоны (то есть необработанную форму, а не определенный тип) из файла. Однако реальность такова, что практически ни один крупный компилятор не поддерживает его и говорит, что никогда не поддержит его. Поэтому он был удален из C ++ 0x.

...