Путаница вокруг явной реализации шаблона

Ну, я думаю, я просто запутался в явной реализации шаблона ~> _<~

  1. Может ли явное объявление экземпляра использовать неявное
    определение экземпляра?
  2. Что, если существуют как явные, так и неявные определения
    в программе? Будут ли они в конечном итоге рухнуть в один?
  3. Имеет ли явное объявление экземпляра какой-либо эффект, когда помещается после
    неявное определение экземпляра?

Также см. Следующий код:

#include <iostream>
#include <vector>

std::vector<int> a;  // Implicit instantiation definition.

// Explicit instantiation declaration.
extern template class std::vector<int>;

int main() {
std::cout << std::vector<int>().size();  // So what?
}

Это вызывает ошибку ссылки

/tmp/ccQld7ol.o: In function `_GLOBAL__sub_I_a':
main.cpp:(.text.startup+0x6e): undefined reference to `std::vector<int, std::allocator<int> >::~vector()'
collect2: error: ld returned 1 exit status

с GCC 5.2, но хорошо работает с clang 3.6. Какой из них правильный в соответствии со стандартом?

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

2

Решение

[Temp.explicit] / P11:

Сущность, которая является предметом явного объявления экземпляра
и это также используется таким образом, что в противном случае вызвало бы неявное
создание экземпляра (14.7.1) в блоке перевода должно быть предметом
явное определение экземпляра где-то в программе;
в противном случае программа некорректна, диагностика не требуется.

1

Другие решения

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

Неявные и явные экземпляры для одного и того же типа могут жить вместе. Неявная реализация создаст слабый символ, явная — «сильный» символ. Сильные символы переопределяют слабые символы, и нет нарушения ODR. Все будет хорошо.

Что касается вашей ошибки, вам нужно удалить extern из вашего явного экземпляра.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector