理解表达式 SFINAE
在 C 编程环境中,表达式 SFINAE(替换失败不是错误)允许您有条件地应用函数基于函数声明中表达式的有效性进行重载。
表达式SFINAE 实际操作
考虑以下代码示例:
示例 1:
template <int I> struct A {}; char xxx(int); char xxx(float); template <class T> A<sizeof(xxx((T)0))> f(T) {}
f() 函数返回一个结构体A 的参数 I 设置为使用模板参数 T 的强制转换值调用 xxx() 的结果的大小(T)0.
示例 2:
struct X {}; struct Y { Y(X) {} }; template <class T> auto f(T t1, T t2) -> decltype(t1 + t2); // #1 X f(Y, Y); // #2 X x1, x2; X x3 = f(x1, x2); // deduction fails on #1 (cannot add X+X), calls #2
在示例 2 中,f() 函数重载允许添加数字类型 (#1)以及从 X 构建 Y (#2)。当使用 x1 和 x2(X 对象)调用 f() 函数时,会选择构造 Y 的重载,因为第一个重载对于 X 对象无效。
常见用例:Trait定义
表达式 SFINAE 通常用于特征定义,它允许您根据类中特定成员函数的存在来定义特征。例如:
struct has_member_begin_test { template <class U> static auto test(U* p) -> decltype(p->begin(), std::true_type()); template <class> static auto test(...) -> std::false_type; }; template <class T> struct has_member_begin : decltype(has_member_begin_test::test<T>(0)) {};
has_member_begin 结构模板可用于检查类是否具有 begin() 成员函数。它使用表达式 SFINAE 来确定 begin() 表达式是否返回有效的类型或表达式,如果有效则返回 std::true_type,否则返回 std::false_type。
重要提示:
表达式 SFINAE 是 C 语言中相对较新的新增内容,并非所有编译器都完全支持它。如果您在代码中遇到表达式 SFINAE 的任何问题,请务必验证您的编译器版本是否支持它。
以上是表达式 SFINAE(替换失败不是错误)在 C 中如何工作以及如何使用它来定义特征并有条件地应用函数重载?的详细内容。更多信息请关注PHP中文网其他相关文章!