[temp.constr.decl]表示我们可以用 constraint expression 来约束模板或函数。
Declarators [dcl.decl]告诉我们,对于函数,我们可以添加一个可选的 *trailing requires子句 * 来约束它,标准的draft n4820甚至给出了这些(看起来毫无意义的)例子:
void f1(int a) requires true;
auto f2(int a) -> bool requires true;
我知道约束模板或概念是有用的,但我看不出这些约束对非模板化函数有什么用。约束非模板化函数的意义是什么?
3条答案
按热度按时间2izufjch1#
作为一个概念,考虑下面的例子
如果
sizeof( long ) == sizeof( long long )
,则程序输出为否则
例如,您可以在计算阶乘的函数中使用这种方法来限制循环迭代的次数或抛出异常。
这是一个演示程序。
它的输出可能是
或
q35jwt9p2#
约束非模板函数的要点之一是能够将约束写入模板类的非模板成员。例如,您可能有这样的类型:
现在,您希望
value
可以从T
复制/移动。但实际上,您希望它可以从T
复制/移动 * 仅 * 只要T
本身是可复制/移动的。那么,如何做到这一点呢?预约束,你需要编写一堆元编程技巧。也许你制作这些构造函数模板,除了复制/移动要求之外,还要求给定的类型
U
与T
相同。或者你可能必须编写一个基类,继承自它,它根据T
的复制/移动能力有不同的专门化。后约束,请执行以下操作:
没有黑客行为。没有将模板应用于不需要模板的函数。它只是工作,并且用户很容易理解正在发生的事情。
这一点对于那些不能是模板的函数来说尤其重要。为了让一个构造函数被认为是一个复制或移动构造函数,它不能是一个模板。复制/移动赋值运算符也是如此。但是这些东西可以有约束。
9o685dep3#
正如一些评论指出的那样,对非模板函数的约束曾经被引入到一些草案中,但最终没有被C20接受。
让我们以N4860(C20的最终草案)作为参考。
相应的例子更容易理解:
我们也可以很容易地验证现代c++编译器拒绝这种用法,例如gcc 12.2clang 16.0.0