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?
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.
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.
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.
" 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.
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With