2015-10-08 3 views
3

Я пытаюсь скомпилировать только с явным шаблоном.Явное создание шаблона

Рассмотрим манекен SNIPPET

#include <vector> 

template struct std::allocator<int>; 
template struct std::vector<int, std::allocator<int>>; 

void fun(){ 
    std::vector<int> v; 
} 

int main(){ 
    fun(); 
}; 

Я хотел бы, чтобы скомпилировать его с

g++ -std=c++11 -fno-implicit-templates fun.cc 

я ожидал, чтобы это работало, однако он жалуется на неразрешенные ссылки на std::vector функций-членов. Не должны ли функции-члены автоматически создаваться вместе с классом std::vector? Как я могу заставить его работать?

Ошибка компилятора:

/tmp/cc1QxQUn.o: In function `std::vector<int, std::allocator<int> >::push_back(int const&)': 
vec.cc:(.text._ZNSt6vectorIiSaIiEE9push_backERKi[_ZNSt6vectorIiSaIiEE9push_backERKi]+0x65): undefined reference to `void std::vector<int, std::allocator<int> >::_M_emplace_back_aux<int const&>(int const&)' 
/tmp/cc1QxQUn.o: In function `std::vector<int, std::allocator<int> >::push_back(int&&)': 
vec.cc:(.text._ZNSt6vectorIiSaIiEE9push_backEOi[_ZNSt6vectorIiSaIiEE9push_backEOi]+0x2a): undefined reference to `void std::vector<int, std::allocator<int> >::emplace_back<int>(int&&)' 
/tmp/cc1QxQUn.o: In function `std::vector<int, std::allocator<int> >::insert(__gnu_cxx::__normal_iterator<int const*, std::vector<int, std::allocator<int> > >, int const&)': 
vec.cc:(.text._ZNSt6vectorIiSaIiEE6insertEN9__gnu_cxx17__normal_iteratorIPKiS1_EERS4_[_ZNSt6vectorIiSaIiEE6insertEN9__gnu_cxx17__normal_iteratorIPKiS1_EERS4_]+0x14d): undefined reference to `void std::vector<int, std::allocator<int> >::_M_insert_aux<int>(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, int&&)' 
vec.cc:(.text._ZNSt6vectorIiSaIiEE6insertEN9__gnu_cxx17__normal_iteratorIPKiS1_EERS4_[_ZNSt6vectorIiSaIiEE6insertEN9__gnu_cxx17__normal_iteratorIPKiS1_EERS4_]+0x166): undefined reference to `void std::vector<int, std::allocator<int> >::_M_insert_aux<int const&>(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, int const&)' 
/tmp/cc1QxQUn.o: In function `std::vector<int, std::allocator<int> >::insert(__gnu_cxx::__normal_iterator<int const*, std::vector<int, std::allocator<int> > >, int&&)': 
vec.cc:(.text._ZNSt6vectorIiSaIiEE6insertEN9__gnu_cxx17__normal_iteratorIPKiS1_EEOi[_ZNSt6vectorIiSaIiEE6insertEN9__gnu_cxx17__normal_iteratorIPKiS1_EEOi]+0x32): undefined reference to `__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > std::vector<int, std::allocator<int> >::emplace<int>(__gnu_cxx::__normal_iterator<int const*, std::vector<int, std::allocator<int> > >, int&&)' 
/tmp/cc1QxQUn.o: In function `void std::vector<int, std::allocator<int> >::_M_assign_dispatch<int const*>(int const*, int const*, std::__false_type)': 
vec.cc:(.text._ZNSt6vectorIiSaIiEE18_M_assign_dispatchIPKiEEvT_S5_St12__false_type[_ZNSt6vectorIiSaIiEE18_M_assign_dispatchIPKiEEvT_S5_St12__false_type]+0x2d): undefined reference to `void std::vector<int, std::allocator<int> >::_M_assign_aux<int const*>(int const*, int const*, std::forward_iterator_tag)' 
/tmp/cc1QxQUn.o: In function `void std::vector<int, std::allocator<int> >::_M_insert_dispatch<int const*>(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, int const*, int const*, std::__false_type)': 
vec.cc:(.text._ZNSt6vectorIiSaIiEE18_M_insert_dispatchIPKiEEvN9__gnu_cxx17__normal_iteratorIPiS1_EET_S9_St12__false_type[_ZNSt6vectorIiSaIiEE18_M_insert_dispatchIPKiEEvN9__gnu_cxx17__normal_iteratorIPiS1_EET_S9_St12__false_type]+0x32): undefined reference to `void std::vector<int, std::allocator<int> >::_M_range_insert<int const*>(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, int const*, int const*, std::forward_iterator_tag)' 
/tmp/cc1QxQUn.o: In function `void std::vector<int, std::allocator<int> >::_M_assign_dispatch<std::move_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > > >(std::move_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > >, std::move_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > >, std::__false_type)': 
vec.cc:(.text._ZNSt6vectorIiSaIiEE18_M_assign_dispatchISt13move_iteratorIN9__gnu_cxx17__normal_iteratorIPiS1_EEEEEvT_S9_St12__false_type[_ZNSt6vectorIiSaIiEE18_M_assign_dispatchISt13move_iteratorIN9__gnu_cxx17__normal_iteratorIPiS1_EEEEEvT_S9_St12__false_type]+0x2d): undefined reference to `void std::vector<int, std::allocator<int> >::_M_assign_aux<std::move_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > > >(std::move_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > >, std::move_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > >, std::forward_iterator_tag)' 
collect2: error: ld returned 1 exit status 

ответ

3

С [temp.explicit]:

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

Таким образом, хотя вы явно инстанцировании std::vector<int>, вы не инстанцировании любой из его шаблонов функций члена - так что вы получаете неопределенные ссылки на все из них (например, _M_emplace_back_aux шаблон функции). Вы должны были бы добавить все те явно:

template void std::vector<int>::_M_emplace_back_aux<int>(int&&); 
template void std::vector<int>::_M_emplace_back_aux<const int&>(const int&); 
template void std::vector<int>::_M_assign_aux<int const*>(int const*, int const*, std::forward_iterator_tag); 
... 

Или просто - пусть неявное инстанцирование просто делать свое дело.

Смежные вопросы