When we explicitly instantiate a template class, the explicit instantiation would instantiate all its member functions, but what about template member functions? The compiler would not know what template parameters would be given to a certain template member function until the member function is called with some parameters somewhere in the program, then how is the compiler supposed to instantiate the template member function? Can someone help me out here? Really appreciate it!
template < typename T > struct foo
{
T bar( T a ) const { return a + 2 ; }
template < int N, typename U > U baz( U a ) const { return a % N ; }
};
// explicit instantiation of class foo<double>
templatestruct foo<double> ; // double foo<double>::bar(double) const is instantiated
// U foo<double>::baz<N,U>(U) const is not instantiated for any N, U
// explicit instantiation of long foo<int>::baz<8,long>(long) const
templatelong foo<int>::baz<8>(long) const ; // fine: U == long is deduced
int main()
{
}
// explicit instantiation of double foo<int>::baz<22,double>(double) const
// template double foo<int>::baz<22>(double) const ; // **** error: invalid type double in a % 22
Thanks for your replies. I understand that the template member functions won't be instantiated now, but about how you explicitly instantiated the template member function here in your code
1 2
// explicit instantiation of long foo<int>::baz<8,long>(long) const
templatelong foo<int>::baz<8>(long) const ; // fine: U == long is deduced
Unless I'm mistaken, I thought that for the declaration or definition of a template member function of a template class, the syntax should be
template<int> template<8,long> long foo<int>::baz(long) const;
Though I tried to run this code myself, and it failed, but could you explain to me why the explicit instantiation should be written the way you did and why mine is wrong? Thanks!
In a template definition we specify the template parameters. The template is defined in terms of the template parameters.
To instantiate a template, we need to specify (or let the compiler deduce) the template arguments.
(For each different set of template arguments, there would be a different template instantiation.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
template < typename T > struct foo
{
T bar( T a ) const { return a + 2 ; }
template < int N, typename U > U baz( U a ) const ;
};
// definition: specify template parameters (T,N,U)
template < typename T >
template < int N, typename U >
U foo<T>::baz( U a ) const { return a % N ; }
// explicit instantiation: specify template arguments (int,20,short)
templateshort foo<int>::baz<20,short>( short ) const ;
// explicit instantiation: specify some template arguments (int,30)
// and let another be deduced (deduced as long)
templatelong foo<int>::baz<30>( long ) const ;