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

1

7

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?

Lorileelorilyn answered 22/9, 2018 at 5:53 Comment(0)
F
8

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.

Footsore answered 22/9, 2018 at 6:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.