其他类型是否有 void_t 的标准概括?
Is there a standard generalization of void_t for other types?
在 C++17 中,我们有 std::void_t
,这让 SFINAE 看起来更漂亮:
template <typename T>
std::void_t<decltype(T::prop)> foo() { /* stuff */ }
只有T::prop
存在,模板函数才会存在。
如果 T::prop
存在,模板函数 foo()
等同于:
template <typename T>
void foo() { /* stuff */ }
否则,代码相当于根本没有声明foo()
。
是否有std::void_t
对标准库中其他类型的泛化,例如:
template<typename T, typename...>
using generic_t = T;
以便下面的代码有效?
template <typename T>
std::generic_t<int, decltype(T::prop)> foo() { /* stuff */ }
相当于
template <typename T>
int foo() { /* stuff */ }
如果 T::prop
存在?
它可能不存在。它没有在文档中链接,因此我怀疑它的存在。但是你可以自己构建这样的类型:
template <class type, class... sfinae_expressions>
using generic_t = type;
为什么需要这样的概括? 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 { };
这并不是说 void
有什么特别之处,您只需要在主要和专业化之间商定一些类型。
void_t
如果您只是直接在 SFINAE 中使用它,则意义不大。您可以将表达式粘贴在其他地方:
template <typename T, class = decltype(T::prop)>
void foo() { /* stuff */ }
此时 return 类型与您正在检查的条件完全不同,所以如果您想要 int
:
template <typename T, class = decltype(T::prop)>
int foo() { /* stuff */ }
在 C++17 中,我们有 std::void_t
,这让 SFINAE 看起来更漂亮:
template <typename T>
std::void_t<decltype(T::prop)> foo() { /* stuff */ }
只有T::prop
存在,模板函数才会存在。
如果 T::prop
存在,模板函数 foo()
等同于:
template <typename T>
void foo() { /* stuff */ }
否则,代码相当于根本没有声明foo()
。
是否有std::void_t
对标准库中其他类型的泛化,例如:
template<typename T, typename...>
using generic_t = T;
以便下面的代码有效?
template <typename T>
std::generic_t<int, decltype(T::prop)> foo() { /* stuff */ }
相当于
template <typename T>
int foo() { /* stuff */ }
如果 T::prop
存在?
它可能不存在。它没有在文档中链接,因此我怀疑它的存在。但是你可以自己构建这样的类型:
template <class type, class... sfinae_expressions>
using generic_t = type;
为什么需要这样的概括? 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 { };
这并不是说 void
有什么特别之处,您只需要在主要和专业化之间商定一些类型。
void_t
如果您只是直接在 SFINAE 中使用它,则意义不大。您可以将表达式粘贴在其他地方:
template <typename T, class = decltype(T::prop)>
void foo() { /* stuff */ }
此时 return 类型与您正在检查的条件完全不同,所以如果您想要 int
:
template <typename T, class = decltype(T::prop)>
int foo() { /* stuff */ }