当前位置: 首页 > 知识库问答 >
问题:

为什么在约束中添加“&&true”使函数模板成为一个更好的重载?

索曾琪
2023-03-14

考虑函数模板foo的以下两个重载:

template <typename T>
void foo(T) requires std::integral<T> {
    std::cout << "foo requires integral\n";
}

template <typename T>
int foo(T) requires std::integral<T> && true {
    std::cout << "foo requires integral and true\n";
    return 0;
}

注意这两个约束之间的区别:第二个约束有一个额外的&true

直观地说,true在连词中是多余的(因为x&&true只是x)。但是,看起来这会产生语义上的差异,因为foo(42)调用第二个重载。

为什么会这样呢?具体来说,为什么第二个函数模板是一个更好的重载?

共有1个答案

柯正谊
2023-03-14

根据[Temp.Constr.Order],特别是[Temp.Constr.Order]/1和[Temp.Constr.Order]/3

/1约束P包含约束Q当且仅当[...][例题:设A和B是原子约束。约束A√B包含A,但A不包含A√B。约束A包含A≠B,但A≠B不包含A。还要注意每个约束都包含自己。-结尾示例]

/3声明D1的约束至少与声明D2相同,如果

  • (3.1)D1D2都是约束声明,D1的关联约束包含了D2的约束;或
  • (3.2)D2没有关联的约束。

如果我们认为Astd::integral Btrue;然后:

  • a√b,即std::integral &true 包含a,即std::integral

意味着下列声明:

// Denote D1
template <typename T>
void foo(T) requires std::integral<T> && true;

// Denote D2
template <typename T>
void foo(T) requires std::integral<T>;

D1的关联约束包含了D2的约束,因此D1至少与D2一样受到约束;根据[temp.func.order]/2,重载结果选择约束更多的声明d1作为最佳匹配:

偏序选择两个函数模板中哪一个比另一个更专门化,方法是依次转换每个模板(请参阅下一段),并使用函数类型执行模板参数推导。扣减过程确定其中一个模板是否比另一个模板更专门化。如果是,则偏序过程选择的模板是更专门的模板。如果两个推导都成功,则偏序选择约束较多的模板(如果存在),如下所确定的。

 类似资料:
  • 现在还有另一种可能的使用方法,我不太明白 这个函数可以很容易地接受任何可转换为a的类型。这很奇怪,因为第一个模板参数(“from”)基本上被删除,并在函数调用时推导出来。下面的函数也可以工作,我很肯定它实际上与前面的函数等效 同样,的类型是在调用时推导出来的。

  • 我正在学习一个视频教程,我想声明一个模板函数作为模板类的朋友。我不知道为什么代码会抛出错误。 编译器抛出错误。 错误: templates\u friends\u 38。cpp:在“void doSomething2(T)[T=int]”的实例化中:templates\u friends\u 38。cpp:40:19:此处需要templates\u friends\u 38。cpp:32:9:错误

  • 问题内容: 在python中进行如下构造是有效的: 我想问一个函数指针被评估为True的逻辑是什么。 为什么在语言中插入这种构造? 问题答案: 在Python中有很多评估结果。从关于布尔运算符的文档中: 在布尔运算的上下文中,以及当控制流语句使用表达式时,以下值将解释为false:,,所有类型的数字零以及空字符串和容器(包括字符串,元组,列表,字典,集合和Frozensets)。所有其他值均解释为

  • 我有一张桌子,不知怎的,同一个人进了我的桌子两次。现在,主键只是一个自动编号,但还有两个字段存在,我想强制它们是唯一的。 例如,这些字段是: 我只想要一张带有唯一PersonNumber和Active=1的唱片 (因此这两个字段的组合必须是唯一的) SQL server中现有表的最佳方式是什么?我可以这样做,如果其他任何人使用与现有值相同的值进行插入,则插入失败,因此我不必在应用程序代码中担心这一

  • 假设我有一个类模板,

  • 问题内容: 我在想, 我确定可以控制添加的类型,因此在MySQL中使用约束作为外键的动机是什么? 它会提高性能吗? 问题答案: 外键强制执行参照完整性。这些约束保证了表中具有引用表的字段的行将永远不会具有表中不存在的值。 外键不需要具有有效的关系数据库(实际上MySQL的默认存储引擎不支持FK),但是对于避免断开关系和孤立行(即参照完整性),它们绝对是必不可少的。是必需的在数据库级别实施参照完整性