简体   繁体   中英

Define and deduce the parameter from Template template parameter

Based on the example on pp. 179

template<template<typename T, typename A> class C, typename T, typename A>
                                                   ^^^^^^^^^^^^^^^^^^^^^^
void erase(C<T, A>&c, const T& item)
{
    c.erase(std::remove(c.begin(), c.end(), item), c.end());
}

int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
{
    list<int> lst;
    lst.push_back(42);
    erase(lst, 42);
}

If I remove the typename T, typename A from the erase function signature, the VS2010 compiler gives the following errors:

 Error 1 error C2065: 'T' : undeclared identifier Error 2 error C2065: 'A' : undeclared identifier Error 3 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int Error 4 error C2143: syntax error : missing ',' before '&' 

Question1 > What is the reason behind these compilation errors.

Is it true that we always have to explicitly define the type parameters used in the template template parameter?

Question2 > When we call the following line, how does compiler deduce the type of A ?

erase(lst, 42)

Is it true that the compiler deduce the type A based on the default argument for template parameter A that is defined in list ?

Refer to list

template < class T, class Allocator = allocator<T> > class list;

And the type A is allocator<T> ?

Question 1

First T and A are parameters to C , not to your erase() template. Therefore, they are not visible to it, what is visible are the second and third parameters you highlight with ^^^. Note that the first parameter is not a typename/class, it is a class template. A class template itself is not a type, only its instantiations are.

To better understand how first T and A are not visible and in fact don't play any role, you can rewrite it like this:

template<template<typename, typename> class C, typename T, typename A>

Question 2

It can deduce A because lst as passed as C<T, A> , so A is the second parameter of lst type's class template.

Finally, you should rewrite your function template in a different way:

template <typename C>
void erase(C& c, const typename C::value_type& item)
{
    c.erase(std::remove(c.begin(), c.end(), item), c.end());
}

This way, you don't restrict number and meaning of C template parameters. In fact, here C can be a non-templated type if wanted.

如果删除这些,则A和T仅在C的上下文中是已知的,而不在您的delete()模板的上下文中是已知的。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM