Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When do we need a .template construct

I made the following program

#include <iostream>
#include <typeinfo>
template<class T>
struct Class
{
    template<class U>
    void display(){

        std::cout<<typeid(U).name()<<std::endl;
        return ;
    }

};


template<class T,class U>
void func(Class<T>k)
{
    k.display<U>(); 

}

int main()
{
    Class<int> d;
    func<int,double>(d);
}

The above program doesn not compile because display() is a template member function so a qualification of .template before display() must be done. Am I right?

But when I made the following program

#include <iostream>
#include <typeinfo>

template<typename T>
class myClass
{
    T dummy;
    /*******/
public:
    template<typename U>
    void func(myClass<U> obj);

};

template<typename T>
template<typename U>

void myClass<T>::func(myClass<U> obj)
{
    std::cout<<typeid(obj).name()<<std::endl;
}
template<class T,class U>
void func2(myClass<T>k)
{
    k.template func<U>(k); //even it does not compile

}
int main()
{
    myClass<char> d;
    func2<char,int>(d);
    std::cin.get();
}

Why k.func<char>(k); does not compile even after giving a .template construct?

like image 914
Prasoon Saurav Avatar asked Aug 17 '10 03:08

Prasoon Saurav


People also ask

What is the need of template?

Templates are frameworks for different data structures. Templates allows you to use standard data structures in your program without any need to write them yourself. Makes your code short and less complicated. A template is a blueprint or formula for creating a generic class or a function.

What is the purpose of a template function?

Function templates. Function templates are special functions that can operate with generic types. This allows us to create a function template whose functionality can be adapted to more than one type or class without repeating the entire code for each type. In C++ this can be achieved using template parameters.

Can a constructor be templated?

As long as you are satisfied with automatic type inference, you can use a template constructor (of a non-template class). @updogliu: Absolutely. But, the question is asking about "a template constructor with no arguments" If there are no function arguments, no template arguments may be deduced.

What is the role of compiler templates?

Template compilation requires the C++ compiler to do more than traditional UNIX compilers have done. The C++ compiler must generate object code for template instances on an as-needed basis. It might share template instances among separate compilations using a template repository.


2 Answers

The < symbol means both "less than" and "begin template arguments." To distinguish between these two meanings, the parser must know whether the preceding identifier names a template or not.

For example consider the code

template< class T >
void f( T &x ) {
    x->variable < T::constant < 3 >;
}

Either T::variable or T::constant must be a template. The function means different things depending which is and which isn't:

  1. either T::constant gets compared to 3 and the Boolean result becomes a template argument to T::variable<>
  2. or T::constant<3> gets compared to x->variable.

The to disambiguate, the template keyword is required before either variable or constant. Case 1:

template< class T >
void f( T &x ) {
    x->template variable < T::constant < 3 >;
}

Case 2:

template< class T >
void f( T &x ) {
    x->variable < T::template constant < 3 >;
}

It would be kind of nice if the keyword were only required in actual ambiguous situations (which are kind of rare), but it makes the parser much easier to write and it prevents such problems from catching you by surprise.

For standardese, see 14.2/4:

When the name of a member template specialization appears after . or -> in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (14.6.2), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template.

like image 160
Potatoswatter Avatar answered Sep 19 '22 18:09

Potatoswatter


Section 5.1 of C++ Templates explains this construct in detail

The below function has a problem

template<class T,class U> 
void func2(myClass<T> k) 
{ 
    k.template func<U>(k); //even it does not compile 

} 

Here T = char and U = int

myclass<char>::func<int>(myclass<char>) 

is being called. However such a function does not exist

Even though in normal circumstances 'char' is convertible to 'int', this does not hold good for explicitly specified template arguments

like image 24
Chubsdad Avatar answered Sep 20 '22 18:09

Chubsdad