C++ essay, the second small note about the template 16.1.3 template parameters

16.1.3 Template parameters

Many times we define the parameter name as T, but in fact we can use any name

such as

template <typename DATA>using partNo = BlobA<DATA>;

Template parameters and scope rules. The usable range of a template parameter name is after its declaration and before the end of the template declaration or definition. Like any other name, template parameters hide the same name declared in the outer scope. However, as in most other contexts, template parameter names cannot be reused within templates:

typedef double A;
template <typename A,typename B>void f(A a,B b)
{
    A tmp = a;
    double B;//错误重复声明模板参数B
}

Because the typename B of B has been declared above, the type of B has been declared below. Also
note that the type of temp is not double, it is the actual parameter type of the template

Template declaration:

The template declaration must contain template parameters

template <typename T> int compare(const T&, const T&);
template <typename T> class Blob;

As with functions, the template name in the declaration does not have to be the same as when it was defined

template <typename T> T calc(const T&,const T&);
template <typename U> U calc(const U&,const U&);

For example, these two template functions are actually the same, so there will be duplicate definitions.

Use class type members

For example, we can use string::size_type, we know the string type, but for the template T::mem, we don’t know the type of T

By default, the C++ language assumes that the name accessed through the scope operator is not a type. So if we want to use a type member of a template type parameter, we must explicitly tell the compiler that the name is a type. We achieve this by using typename.

template <typename T>
typename T::value_type top(const T&c)
{
    if(!c.empty())
        return c.back();
    else
        return typename T::value_type();
}

Our top function expects a container type argument. It uses typename to indicate the return type and generates a value-initialized element to return to the caller when there is no element in c.

Then we look at the code

int main()
{
    int b;
    std::vector<int> vec;
    top(vec);
//    std::cout<<partNo<int>::count()<<std::endl;
    return 0;
}

If vec is passed in, it is correct. If a is passed in because it is an int, it is wrong. This is all thanks to the fact that we informed the compiler in advance.

Guess you like

Origin blog.csdn.net/qq_32783703/article/details/104601574