Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

function template with unused template parameter

template<typename T>
struct a 
{ 
  using type = int;
  typename T::type i;
};

template<typename T, typename = a<T>>
void f1(T) {}

template<typename T, typename = typename a<T>::type>
void f2(T) {}

int main()
{
  f1<int>(1); // ok
  f2<int>(1); // error

  return 0;
}

An instantiation of a<int> should be an error because int::type is illegal. But it seems that f1<int> can't cause the instantiation of a<T>, but f2<int> can. What's the reason?

like image 404
olist Avatar asked Jun 15 '18 10:06

olist


People also ask

Can a template parameter be a function?

A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.

Can a template be a template parameter?

Templates can be template parameters. In this case, they are called template parameters. The container adaptors std::stack, std::queue, and std::priority_queue use per default a std::deque to hold their arguments, but you can use a different container.

Why do we use :: template template parameter?

8. Why we use :: template-template parameter? Explanation: It is used to adapt a policy into binary ones.

What is the validity of template parameters?

Clarification: Template parameters are valid inside a block only i.e. they have block scope. 4.


1 Answers

When type is used as the template argument (including default template argument), it's not required to be complete type.

A template argument for a type template parameter must be a type-id, which may name an incomplete type:

So for f1, the default template argument is a<T> and it doesn't have to be complete. Given f1<int>(1); a<int> doesn't need to be instantiated.

But when you refer to the member of the class template, as the default template argument typename a<T>::type of f2, a<T> has to be complete type and then cause implicit instantiation.

When code refers to a template in context that requires a completely defined type, or when the completeness of the type affects the code, and this particular type has not been explicitly instantiated, implicit instantiation occurs. For example, when an object of this type is constructed, but not when a pointer to this type is constructed.

This applies to the members of the class template: unless the member is used in the program, it is not instantiated, and does not require a definition.

So given f2<int>(1);, a<int> will be instantiated and then cause the compilation error.

like image 103
songyuanyao Avatar answered Sep 26 '22 01:09

songyuanyao