c++ 概念是SFINAE的变体吗

nuypyhwy  于 2022-11-27  发布在  其他
关注(0)|答案(1)|浏览(137)

SFINAE是一种允许在模板化函数的直接上下文中使用无效表达式和/或类型的技术,而concept似乎具有相同的效果,因为我们只允许使用表达式和类型(in requires-expression),并且如果所有表达式和/或类型都有效,则约束表达式为真,否则为false。在我看来,concept不能做任何超过SFINAE所能做的事情,反过来也是如此。
我的理解是否正确?如果不正确,在什么情况下,我们只能通过使用该概念,或者通过使用SFINAE,但使用其他方式会导致错误?如果不存在这样的场景,该概念是否只是使用技术SFINAE的一种优雅/现代方式(即它们本质上是等同的)?

更新:

唯一的区别是,我们要检查的某些表达式和类型分散在SFINAE的声明中,相反,我们要检查的某些表达式和类型集中在单个 concept-definitionconstraint-expression 中,并使用声明中声明的concept它们的效果基本上依赖于无效的表达式和类型

ugmeyewa

ugmeyewa1#

它们并不等价。概念可以出现在更多的地方,并且可以通过包含来部分排序。一些例子:

    • 1.概念包容可用于对重载进行排名。**对于SFINAE,this is an error
template <typename T>
auto overload(T) -> std::enable_if_t<std::is_copy_constructible_v<T>>;
template <typename T>
auto overload(T) -> std::enable_if_t<std::is_move_constructible_v<T>>;

void test() {
  overload(1); // error: ambiguous
}

通过概念,this works

void overload(std::copy_constructible auto);
void overload(std::move_constructible auto);

void test() {
  overload(1);
}
    • 2.类似地,概念包含可用于对部分专门化进行排名。**
    • 3.允许在非模板成员函数上使用概念,因此它们可以约束特殊的成员函数。**

因为复制构造函数不是模板,所以SFINAE永远不适用。当一个人在概念之前需要条件行为(例如,如果类模板的模板参数本身是平凡的,则需要平凡的复制构造函数)时,他必须有条件地引入不同的基类。

    • 4.概念可以约束演绎。**

可以静态Assert返回的类型满足您的要求,而无需Assert精确的类型。

std::integral auto i = 1;
    • 5.概念可用于缩写函数模板。**
void f(std::integral auto);

相关问题