Шаблонные классы и включают защиту в C++

Действительно ли мудро иметь, включают защиту вокруг шаблонных классов?

Разве шаблонные классы, как предполагается, не повторно анализируются каждый раз, когда Вы ссылаетесь на них с другой реализацией?

N.B В Visual C++ 2008 я не получаю ошибок при объединении двух...

7
задан Bill Kotsias 8 March 2010 в 12:28
поделиться

4 ответа

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

Определения шаблонов обычно (т.е. если вы не используете export или не делаете что-то особенное) находятся в заголовочных файлах, которые должны иметь свой include guard. Добавлять его для определения шаблона бесполезно, но не вредно.

8
ответ дан 6 December 2019 в 07:25
поделиться

Вам нужна охрана. Рассмотрим этот код:

// this is t.h
template <typename T>
void f( T t ) {
}

// this is t.cpp
#include "t.h"
#include "t.h"

int main() {
    f( 1 );
}

Это дает ошибку:

t.h:2: error: redefinition of 'template<class T> void f(T)'
t.h:2: error: 'template<class T> void f(T)' previously declared here

Кроме того, заголовки, которые содержат шаблоны, обычно также содержат не шаблонный код.

12
ответ дан 6 December 2019 в 07:25
поделиться

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

2
ответ дан 6 December 2019 в 07:25
поделиться

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

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

Неважно, что компилятор ничего не разбирает; это его работа. Вы просто должны предоставить содержимое один раз, после чего компилятор уже видел его и может обращаться к нему столько раз, сколько ему нужно.

2
ответ дан 6 December 2019 в 07:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: