c++ - 是否有其他类型的 void_t 的标准概括?

标签 c++ sfinae c++17

在 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 存在?

最佳答案

为什么您需要这样的概括? 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 */ }

此时返回类型与您正在检查的条件完全不同,所以如果您想要 int:

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

关于c++ - 是否有其他类型的 void_t 的标准概括?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44715756/

相关文章:

c++ - 在模板评估期间允许隐式类型转换

c++ - 主函数可以是模板吗? (安全的命令行参数解析)

c++ - SFINAE on Error in Dependent Type 导致意外的硬错误

c++ - 如何在 vector 中 emplace_back (追加)而不声明变量..?

c++ - 将 vector 成员(结构)传递给函数

c++ - 对字符数组感到困惑

模板化基类的 C++ 函数模板专门化

c++ - 为什么我必须调用 operator<< 作为 SFINAE 使用 void_t 的方法?

C++ 范围-v3 : trying to chain together transforms

c++ - 自 C++17 允许显式指定某些类模板参数以来,构造函数的模板参数推导是否可用?