Создание шаблона C ++ - Почему мой всегда должен быть явным, в отличие от STL? - PullRequest
2 голосов
/ 30 сентября 2011

Любой из моих проектов C ++ будет генерировать ошибку компоновщика, если я не включу явную реализацию шаблона для каждого шаблонного класса / метода / функции, которую я создаю и использую.

Классы STL, похоже, не имеют такой проблемы.

Есть ли какой-то простой кодекс поведения (предназначенный для каламбура), которого я могу придерживаться, который позволяет отложить инстанцирование, например, STL?

Спасибо за внимание.

Ответы [ 3 ]

8 голосов
/ 30 сентября 2011

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

1 голос
/ 30 сентября 2011

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

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

1 голос
/ 30 сентября 2011

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

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

например, поместите:

template typename<T> foo(T val) { std::cerr << "DEFAULT"; }

в заголовочный файл и его специализацию для int:

template<> foo<int>(int val) { std::cerr << "INT"; }

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

...