type_trait<T>{} 中的 {} 在模板参数中的作用是什么?

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

我经常在模板代码中看到此 {} 的出现。我不确定我明白它在做什么。例如:

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

这里的{}是什么?它是在实例化类型吗?模板参数是什么意思?

AFAIK 实例化一个类型意味着创建一个对象。您如何在这种情况下创建对象?它只是创建一个虚拟对象吗?为什么要这样做?这是什么意思和目的?

在此上下文中,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() 和 returns 的值。因此,std::is_copy_constructible<T&>{} 产生一个 std::is_copy_constructible<T&> 类型的值,但由于我们在需要 bool 的上下文中使用它,因此调用了隐式转换运算符。