- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
(以下所有ISO标准引用均引用N4659: March 2017 post-Kona working draft/C++17 DIS,并且所有示例程序结果在GCC和Clang上对于C++ 11,C++ 14和C++ 17都是一致的)
考虑以下示例:
#include <initializer_list>
// Denote as A.
void f(float) {}
// Denote as B.
void f(std::initializer_list<int>) {}
int main() {
// Denote call as C1.
f(1.5F); // Overload resolution picks A (trivial).
// Denote call as C2.
f({1.5F}); // Overload resolution picks B (and subsequently fails; narrowing).
return 0;
}
error: type 'float' cannot be narrowed to 'int' in initializer list [-Wc++11-narrowing]
f({1.5F});
函数调用发现void f(std::initializer_list<int>)
是唯一的最佳可行函数,其排名比void f(float)
更好? Afaics这与[over.ics.list]/4和[over.ics.list]/9冲突(请参阅下面的详细信息)。 std::initializer_list<>
(以及有关此主题的各种SO问题)的重载解析的特殊规则,其中,
std::initializer_list<>
是首选,由
[over.match.list]/1来控制。但是,狂热,这在这里不适用(或者,如果我错了,至少可以说与
[over.ics.list]/4中显示的标准示例有冲突)。
candidate_functions(C1) = { void f(float),
void f(std::initializer_list<int>) }
candidate_functions(C2) = { void f(float),
void f(std::initializer_list<int>) }
viable_functions(C1) = { void f(float),
void f(std::initializer_list<int>) }
viable_functions(C2) = { void f(float),
void f(std::initializer_list<int>) }
f(1.5F)
具有身份标准转换(不转换),因此可以(平分和明确地)选择A的精确匹配项(按照
[over.ics.scs]/3)作为最佳可行函数。
best_viable_function(C1) = void f(float)
f({1.5F})
的隐式转换序列对可行候选者进行排名由
[over.ics.list]/1控制:
When an argument is an initializer list ([dcl.init.list]), it is not an expression and special rules apply for converting it to a parameter type.
float
类型的A的匹配,可应用
[over.ics.list]/9,尤其是
[over.ics.list]/9.1 [
强调矿]:
Otherwise, if the parameter type is not a class:
(9.1) if the initializer list has one element that is not itself an initializer list, the implicit conversion sequence is the one required to convert the element to the parameter type; [ Example:
void f(int);
f( {'a'} ); // OK: same conversion as char to int
f( {1.0} ); // error: narrowing— end example ]
[...]
f({1.5F}}
匹配到
f(float)
的隐式转换序列与
float
到
float
的转换序列相同;即身份转换以及随后的完全匹配。但是,按照上面的示例,由于调用C2甚至不会导致模棱两可的最佳可行函数,因此我的逻辑中肯定存在一些缺陷。
Otherwise, if the parameter type is
std::initializer_list<X>
and all the elements of the initializer list can be implicitly converted toX
, the implicit conversion sequence is the worst conversion necessary to convert an element of the list toX
, or if the initializer list has no elements, the identity conversion. This conversion can be a user-defined conversion even in the context of a call to an initializer-list constructor. [ Example:void f(std::initializer_list<int>);
f( {} ); // OK: f(initializer_list<int>) identity conversion
f( {1,2,3} ); // OK: f(initializer_list<int>) identity conversion
f( {'a','b'} ); // OK: f(initializer_list<int>) integral promotion
f( {1.0} ); // error: narrowing
[...]— end example ]
float
元素转换为
int
所需的最差转换,这是一个转换排序的标准转换序列(
[over.ics.scs]/3),尤其是按照
[conv.fpint]/1变窄的转换。
best_viable_function(C2) = void f(float) ?
最佳答案
列表初始化序列:一种序列转换为std::initializer_list
时的特殊情况排序
[over.ics.rank]/3.1适用于这种情况,并且优先于[over.ics.rank]/3的其他规则[强调矿]:
List-initialization sequence
L1
is a better conversion sequence than list-initialization sequenceL2
if
- (3.1.1)
L1
converts tostd::initializer_list<X>
for someX
andL2
does not, or, if not that- (3.1.2) [...]
even if one of the other rules in this paragraph would otherwise apply. [ Example:
void f1(int); // #1
void f1(std::initializer_list<long>); // #2
void g1() { f1({42}); } // chooses #2
void f2(std::pair<const char*, const char*>); // #3
void f2(std::initializer_list<std::string>); // #4
void g2() { f2({"foo","bar"}); } // chooses #4— end example ]
f({1.5F});
调用实际上具有含糊的排名规则。最佳可行的功能,已包含在
CWG Defect Report 1589 [
强调我的]中:
1589. Ambiguous ranking of list-initialization sequences
Section: 16.3.3.2 [over.ics.rank]
Status: CD4
Submitter: Johannes Schaub
Date: 2012-11-21[Moved to DR at the November, 2014 meeting.]
The interpretation of the following example is unclear in the current wording:
void f(long);
void f(initializer_list<int>);
int main() { f({1L});The problem is that a list-initialization sequence can also be a standard conversion sequence, depending on the types of the elements and the type of the parameter, so more than one bullet in the list in 16.3.3.2 [over.ics.rank] paragraph 3 applies:
[...]
对于上面的示例,这些项目符号给出相反的结果,
是在其中选择的实现差异。
[...]
拟议的解决方案(2014年6月):
此问题已通过解决问题得到解决
1467。
CWG Defect Report 1467最终还解决了DR 1589,特别是在[ 强调矿]的上方添加了[over.ics.rank] / 3中引用的相关部分:
1467. List-initialization of aggregate from same-type object
[...]
Proposed resolution (June, 2014):
[...]
- Move the final bullet of 16.3.3.2 [over.ics.rank] paragraph 3 to the beginning of the list and change it as follows:
[...]
even if one of the other rules in this paragraph would otherwise apply. [Example: ... — end example]
This resolution also resolves issues 1490, 1589, 1631, 1756, and 1758.
此后,诸如GCC和Clang之类的编译器已将DR 1467向后移植到较早的标准(C++ 11和C++ 14)。
关于c++ - 使用std::initializer_list参数的非成员函数(/非构造函数上下文)的重载解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62302073/
test = (function(){var key = 200; return {getKey : function(){return key} }; })(); test.
如果这个问题可能一直被问到,我很抱歉,但我进行了搜索,但找不到足够的答案。 如果公共(public)成员/方法正在访问私有(private)成员/字段,如何禁用它们的继承? 所以考虑一下: publi
重要的澄清:一些评论者似乎认为我是从 union 复制的。仔细查看 memcpy,它从一个普通的旧 uint32_t 地址复制而来,该地址不包含在 union 中。另外,我正在(通过 memcpy)复
spinner 通常只显示一个字符串,在我想分配 IDpersonne 和 Name 的情况下,旋转器必须告诉我名字。当我得到选定的项目时,我必须得到 ID。我该怎么做? 最佳答案 我假设您已将项目排
A 类的实例是 B 类的公共(public)成员。B 类的实例也是 A 的公共(public)成员。在什么情况下可能需要这种实现?我的意思是是否有一个或多个标准场景需要这种实现方式?更具体的细节:我有
我如何设置我的 web.config 以使用表单例份验证,将成员身份提供程序设置为 ActiveDirectoryMembershipProvider 并使用内置登录控件。这样我就可以使用有效的事件目
这个问题已经有答案了: Should methods in a Java interface be declared with or without a public access modifier?
因此根据定义,类中的私有(private)数字在序列化时以类名作为前缀。这对我来说是一个问题,我希望能够序列化/保存/反序列化一个确切的对象,但是 php 所做的是给我另一个 classname+va
我实现了一个成员? clojure 中的函数如下: (defn member? [item seq] (cond (empty? seq) false (= item (first
我在这里的问题似乎总是与使用函数有关。它仍然让我困惑!在本教科书练习中,我被要求按值传递结构,然后调整它并按引用传递。最初我设计的代码是在 main 中完成所有工作。现在我正在传递值。所以我添加了新函
所以我有这些变量 List files, images = new List(); string rootStr; 还有这个线程函数 private static int[] thread_searc
我对 C++ 模板和尝试弄清楚部分模板特化还比较陌生。我正在使用模板实现几个相关的数据结构:用于概率存在/不存在查询的布隆过滤器(基于位数组),以及用于丰度查询的计数布隆过滤器(带有整数数组)。我从以
例如在 java 中,我在外部类和内部类中声明并初始化了一个 JButton,我决定在某些情况下将其隐藏,这是一种安全的编程实践吗? 最佳答案 内部类的全部目的是它们可以访问到环绕内部类的外部类。 所
我有一个使用库进行通信的类: class Topic { Topic( Type T, String name ); }; class Reader { Reader (Topic, Stri
我在两个单独的文件中有以下代码。 package animal; public class Frog { protected void ribbit() { Syste
我有一个分数列表。使用这些,我需要从 redis 排序集中提取值。 我知道我可以使用 zrangebyscore - 但如果我提供的列表中的分数不连续怎么办?在这种情况下,我不能依赖 zrangeby
过去几年我一直被 C# 编码宠坏了,现在我又回到了 C++ 并发现我在处理本应很简单的东西时遇到了麻烦。我正在为 gamedev 使用名为 DarkGDK 的第三方库(任何以 db 为前缀的命令),但
我正在关注 Brian Harvey 从 2011 年开始在 UC Berkeley site 上的 SICP 讲座。 .他正在使用 STk interpreter教这门课,我正在使用带有 DrRac
在这段代码中,为什么在运算符重载中无法访问我的类的私有(private)字段? (请注意,这只是一个 MRE,不是完整代码) template class Frac template Frac o
在命名命名空间类中,我将一个类(位于全局命名空间中)声明为友元。 但是,后一个类不能访问前一个类的私有(private)成员。为什么是这样?有什么办法可以解决吗? Bob.h namespace AB
我是一名优秀的程序员,十分优秀!