How would template member functions be instantiated when a template class is explicitly instantiated

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!
how is the compiler supposed to instantiate the template member function?
It does not instantiate template member functions. Those are instantiated only when you actually use them.
> how is the compiler supposed to instantiate the template member function?

When we declare an explicit instantiatiation of a template member function, we have to specify the template arguments that can't be deduced

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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>
template struct 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
template long 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 

http://coliru.stacked-crooked.com/a/1d754b2eeb80d2fd
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
template long 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
1
2
3
4
5
template <typename T1> class Foo
{
    template <typename T2> void Bar(T2  t);
};
template<T1> template<T2> void Foo<T1>::Bar(T2 t);

Similarly, the explicit instantiation 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!
Last edited on
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)       
template short foo<int>::baz<20,short>( short ) const ;        

// explicit instantiation: specify some template arguments (int,30)
// and let another be deduced (deduced as long)       
template long foo<int>::baz<30>( long ) const ; 

http://coliru.stacked-crooked.com/a/1002294841168f10
I got confused over definition and explicit instantiation. Thanks for your elaboration. It's really helpful!
Topic archived. No new replies allowed.