对于其他类型,是否存在void_t的标准泛化?

Ber*_*ard 9 c++ sfinae c++17

在C++ 17中,我们有std::void_t,这使得SFINAE看起来更好:

template <typename T>
std::void_t<decltype(T::prop)> foo() { /* stuff */ }
Run Code Online (Sandbox Code Playgroud)

模板函数仅在T::prop存在时才存在.

如果T::prop存在,模板函数foo()将等效于:

template <typename T>
void foo() { /* stuff */ }
Run Code Online (Sandbox Code Playgroud)

否则,代码相当于根本没有声明foo().

是否std::void_t对标准库中的其他类型进行了泛化,例如:

template<typename T, typename...>
using generic_t = T;
Run Code Online (Sandbox Code Playgroud)

以便下面的代码有效?

template <typename T>
std::generic_t<int, decltype(T::prop)> foo() { /* stuff */ }
Run Code Online (Sandbox Code Playgroud)

这相当于

template <typename T>
int foo() { /* stuff */ }
Run Code Online (Sandbox Code Playgroud)

如果T::prop存在?

Bar*_*rry 5

你为什么需要这样的概括?void_t有点特别之处在于它可以帮助您轻松编写类型特征,因为您可以拥有某个类型默认的主要void和使用的特殊化void_t.例如:

template <class T, class = void>
struct has_prop : std::false_type { };

template <class T>
struct has_prop<T, std::void_t<decltype(T::prop)>> : std::true_type { };
Run Code Online (Sandbox Code Playgroud)

并不是说有什么特别之处void,你只需要在主要和专业化之间达成一些商定的类型.

void_t如果您只是直接在SFINAE中使用它,那就没有多大意义了.你可以把表达式粘贴在其他地方:

template <typename T, class = decltype(T::prop)>
void foo() { /* stuff */ }
Run Code Online (Sandbox Code Playgroud)

此时返回类型与您正在检查的条件完全分开,因此如果您需要int:

template <typename T, class = decltype(T::prop)>
int foo() { /* stuff */ }
Run Code Online (Sandbox Code Playgroud)