В этом контексте type_trait<T>{}
эквивалентно type_trait<T>::value
.Ваш пример эквивалентен следующему:
std::enable_if_t<std::is_copy_constructible<T&>::value && !std::is_same<T, MyClass>::value>>
Как правило, некоторые преимущества использования type_trait<T>{}
вместо type_trait<T>::value
:
- C ++ 17 добавлено
type_trait_v<T>
.До C ++ 17 type_trait<T>{}
такой же краткий. type_trait<T>{}
работает с диспетчеризацией тегов.То есть foo(type_trait<T>{})
может вызывать различные перегрузки, основанные на значении type_trait<T>::value
, потому что значения true и false являются разными типами.
Это работает, потому что признаки типа наследуются от std::integral_constant<bool, Value>
, который имеет constexpr operator bool()
, который возвращает значение.Таким образом, std::is_copy_constructible<T&>{}
создает значение типа std::is_copy_constructible<T&>
, но, поскольку мы используем его в контексте, который ожидает bool
, вызывается оператор неявного преобразования.