Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the role of the {} in type_trait<T>{} when used in a template parameter?

I'm often seeing occurrences of this {} in templated code. I'm not sure I understand what's it doing. For example:

std::enable_if_t<std::is_copy_constructible<T&>{} && !std::is_same<T, MyClass>{}>>

What is {} here? Is it instantiating the type? What does that mean as a template parameter?

AFAIK instantiating a type means creating an object. How can you create an object in this context? Is it just creating a dummy object? And why do that? What is the meaning and purpose of this?

like image 419
KeyC0de Avatar asked Sep 22 '18 05:09

KeyC0de


People also ask

What are template parameters?

In UML models, template parameters are formal parameters that once bound to actual values, called template arguments, make templates usable model elements. You can use template parameters to create general definitions of particular types of template.

What is a template template parameter in C++?

In C++ this can be achieved using template parameters. 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.

Which is the correct example of template parameters?

For example, given a specialization Stack<int>, “int” is a template argument. Instantiation: This is when the compiler generates a regular class, method, or function by substituting each of the template's parameters with a concrete type.

What is Typename in C++ template?

" typename " is a keyword in the C++ programming language used when writing templates. It is used for specifying that a dependent name in a template definition or declaration is a type.


1 Answers

In this context, type_trait<T>{} is equivalent to type_trait<T>::value. Your example is equivalent to the following:

std::enable_if_t<std::is_copy_constructible<T&>::value && !std::is_same<T, MyClass>::value>>

In general, some benefits of using type_trait<T>{} instead of type_trait<T>::value are:

  • C++17 added type_trait_v<T>. Prior to C++17, type_trait<T>{} is just as terse.
  • type_trait<T>{} works with tag dispatch. That is to say, foo(type_trait<T>{}) can call different overloads based on the value of type_trait<T>::value because the true and false values are distinct types.

This works because type traits inherit from std::integral_constant<bool, Value> which has a constexpr operator bool() which returns the value. Thus, std::is_copy_constructible<T&>{} produces a value of type std::is_copy_constructible<T&>, but since we are using it in a context that expects a bool, the implicit conversion operator is called.

like image 189
Justin Avatar answered Nov 14 '22 20:11

Justin