显式模板实例化

时间:2015-10-08 16:49:45

标签: c++ templates c++11

我正在尝试使用显式模板实例进行编译。

考虑这个虚拟片段

#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

1 个答案:

答案 0 :(得分:3)

来自[temp.explicit]:

  

命名类模板特化的显式实例化也是一个显式实例化   每个成员的同类(声明或定义)(不包括从基础继承的成员   类和成员模板)之前未明确专门用于翻译   包含显式实例化的单元,除非如下所述。

因此,当您明确地实例化std::vector<int>时,您并未实例化其任何成员函数模板 - 因此您将获得所有这些模板的未定义引用(例如{{1是一个函数模板)。您必须明确添加所有这些内容:

_M_emplace_back_aux

或者只是 - 让隐式实例化做它的事情。