- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
考虑这一对简单的函数模板。
template <typename T>
void foo(T& ) { std::cout << __PRETTY_FUNCTION__ << '\n'; }
template <typename C>
void foo(const C& ) { std::cout << __PRETTY_FUNCTION__ << '\n'; }
如果我们使用非常量参数调用 foo
:
int i = 4;
foo(i);
基于 [over.ics.rank]/3.2.6 首选 T&
重载,因为推导的引用 int&
较小 cv - 比推导的引用 const int&
限定。
但是,如果我们使用 const 参数调用 foo
:
const int ci = 42;
foo(ci);
const C&
重载是首选,因为它基于 [over.match.best]/1.7“更专业”。但确定这一点的规则是什么?我的理解是,您合成 C
的类型(称为 M
)并尝试对 foo(M)
执行推导 - 但那会成功(T == M
)。只有右值会导致推导失败 - 但编译器如何知道它必须在综合步骤中选择右值?
最佳答案
免责声明:我们考虑的类型始终是参数类型。类型/值类别/等等。所传递的实际参数仅在重载决策中考虑,从不按部分顺序考虑。
部分排序考虑两个“回合”中的重载,其中一个模板始终是参数模板,另一个模板是参数模板。 [temp.deduct.partial]/2:
For each of the templates involved there is the original function type and the transformed function type. [..] The deduction process uses the transformed type as the argument template and the original type of the other template as the parameter template. This process is done twice for each type involved in the partial ordering comparison: once using the transformed template-1 as the argument template and template-2 as the parameter template and again using the transformed template-2 as the argument template and template-1 as the parameter template.
您应该熟悉转换后的"template"的生成方式。这在第 §14.5.6.2/3 中进行了规定。
To produce the transformed template, for each type, non-type, or template template parameter (including template parameter packs (14.5.3) thereof) synthesize a unique type, value, or class template respectively and substitute it for each occurrence of that parameter in the function type of the template.
所以我们的(转换后的)参数模板是
void foo( Unique1& );
void foo( Unique2 const& );
[temp.deduct.partial]/3 &/4:
The types used to determine the ordering depend on the context in which the partial ordering is done:
- In the context of a function call, the types used are those function parameter types for which the function call has arguments. [..]
Each type nominated above from the parameter template and the corresponding type from the argument template are used as the types of
P
andA
.
因此我们有两个回合,并且在两个回合中我们都有一个类型 P
和类型 A
:
第 1 回合:P1
: T const&
A1
: Unique1&
第二回合:P2
: T&
A2
: Unique2 const&
但在乐趣开始之前,也会对这些类型执行一些转换 - 我缩写为 [temp.deduct.partial]/5 和/7:
P
或A
是引用,然后它们被它们引用的类型替换。 请注意,删除的 cv 限定符将被“记住”以供稍后使用。 [temp.deduct.partial]/6:
If both
P
andA
were reference types (before being replaced with the type referred to above), determine which of the two types (if any) is more cv-qualified than the other; otherwise the types are considered to be equally cv-qualified for partial ordering purposes. The result of this determination will be used below.
这样我们就剩下
第 1 回合:P1
: T
A1
: Unique1
第二回合:P2
: T
A2
: Unique2
现在我们执行演绎 - 通过设置 T=Unique[1/2]
显然在两轮中都成功了。来自 [temp.deduct.partial]/8:
If deduction succeeds for a given type, the type from the argument template is considered to be at least as specialized as the type from the parameter template.
这给了我们Unique1&
至少与 T const&
一样专业,以及Unique2 const&
至少与 T&
一样专业.
然而,这就是 [temp.deduct.partial]/(9.2) 介入的地方:
If, for a given type, deduction succeeds in both directions (i.e., the types are identical after the transformations above) and both
P
andA
were reference types (before being replaced with the type referred to above):
[..]; otherwise,
if the type from the argument template is more cv-qualified than the type from the parameter template (as described above), the parameter type is not considered to be at least as specialized as the argument type.
记住的简历限定符开始发挥作用。 A2
比P2
“更符合简历要求(如上所述)” ,因此 P2
不被认为至少像 A2
一样专业。
最后,[temp.deduct.partial]/10:
Function template
F
is at least as specialized as function templateG
if, for each pair of types used to determine the ordering, the type fromF
is at least as specialized as the type fromG
.
F
is more specialized thanG
ifF
is at least as specialized asG
andG
is not at least as specialized asF
.
意味着自从类型 T&
至少不如 Unique2 const&
特化我们已经确定 T const&
至少与 Unique1&
一样专业,T const&
-overload 比 T&
更专业-重载。
上述第 9 段中的规则目前属于 CWG #2088 的主题。由 R. Smith 四个月前创建:
The late tiebreakers for lvalue-vs-rvalue references and cv-qualification in 14.8.2.4 [temp.deduct.partial] paragraph 9 are applied
If, for a given type, deduction succeeds in both directions (i.e., the types are identical after the transformations above) and both
P
andA
were reference types (before being replaced with the type referred to above):然而,这是基于错误的假设。 [..] 我们需要决定规则是“双向推演成功”还是“类型相同”。看来后者更合理。
这不会改变建立的结果,因为我们得到的类型确实是相同的。
关于c++ - 重载解析和部分模板排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31051189/
我在使用 io-ts 时遇到一些问题。我发现它确实缺乏文档,我取得的大部分进展都是通过 GitHub issues 取得的。不,我不明白 HKT,所以没有帮助。 基本上,我在其他地方创建一个类型,ty
我必须创建一个正则表达式来搜索整个文件,以找到与 Java XML 解析器的第一部分(但不是第二部分)的匹配项。这将用于防止某些 XXE 攻击。不幸的是,它确实必须是单个正则表达式,并且它确实需要搜索
我有一些简单的 Shared/_Header.cshtml 文件中的内容。 My Shared/_Layout.cshtml 通过调用插入该代码 @Html.Partial("_Header") 目前
我有一个 if-else 语句,其中: 条件 1:ID 匹配并且自动填充某些字段。然后 if 语句只填充其余字段 条件 2:ID 不匹配,所有字段均为空白。 ELSE 语句将它们全部填充 当我使条件
我正在开发一个单页滚动网站。我正在尝试实现 ScrollMagic 并固定第一部分,以便网站的其余部分滚动到固定部分的顶部。我尝试创建一个 jsfiddle 来显示问题,但我似乎无法让 jsfiddl
这是我的情况: 我想使用 Google AdWords 的转换脚本,但出于某种原因,他们代码段的 javascript 部分在我的页面上添加了一些我似乎无法摆脱的不需要的空白。 所以我正在查看的选项纯
寻找一种优雅的方式在页面上添加一次脚本,就是这样。 我有一个需要 2 个 CSS 文件和 2 个 JS 文件的部分 View 。在大多数地方,只需要其中 1 个部分 View 。但在单个页面上,我需要
我想要一个网站,该网站始终具有相同的部分,具有相同的 id 以及我想要显示的所有内容。我对 javascript 不太了解,我想知道如何删除除特定部分之外的所有内容。 最好的方法是否是只执行一个循环来
SQL 语句教程 (11) Group By 我们现在回到函数上。记得我们用 SUM 这个指令来算出所有的 Sales (营业额)吧!如果我们的需求变成是要算出每一间店 (store_name)
我试图理解部分并认为我已经明白了。基本上,这是一种将部分应用程序应用于二元运算符的方法。所以我了解所有(2*) , (+1)等例子就好了。 但是在 O'Reilly Real World Haskel
有没有办法禁止在部分中覆盖给定的关键字参数?假设我要创建函数 bar总是有 a设置为 1 .在以下代码中: from functools import partial def foo(a, b):
我有这个使用节的 OpenMP 代码 #pragma omp parallel sections num_threads(8) { printf_s("Allo fro
我正在尝试重新创建 Apple 制作的有缺陷的 CNContactPickerViewController,因此我有一个数据数组 [CNContact],我需要将其整齐地显示在 UITableView
我有一个相对布局,其中包含一些 float 在 GridView 上的 TextView 。当我在网格中选择一个项目时,布局向下移动到屏幕的尽头,只有大约 1/5 的部分是可见的。这是使用简单的翻译动
我想在我的 tableView 中有两个部分。我希望将项目添加到第 0 节,然后能够选择一行以将其从第 0 节移动到第 1 节。到目前为止,我已将这些项目添加到第 0 节,但是当它关闭时数据不会加
我正在以自由职业者的身份开发支付控制软件,但我有一些关于 mysql 的问题。 。我有一个用作日志的表,名为“Bitacora”。在表中,我有一个名为 idCliente 的列,它是自己表中一个人的
我有一个 PFQueryTableViewController,我想向 tableview 添加部分,我这样尝试: - (PFQuery *)queryForTable { PFQuery *qu
我正在尝试编写一个查询,将部分匹配项与存储的名称值进行匹配。 我的数据库如下所示 Blockquote FirstName | Middle Name | Surname --------------
我正在开发一个语音备忘录应用程序,并且正在将文件保存到表格 View 中。我希望默认文件名显示为“新文件 1”,如果使用“新文件 1”,则它会显示为“新文件 2”,依此类推。 我正在尝试使用 do-w
我有以下简单的 HTML 布局 .section1 { background: red; } .section2 { background: green; } .section3 { ba
我是一名优秀的程序员,十分优秀!