jjzjj

c++ - 当参数是初始化列表且参数是引用时的重载解析

coder 2024-02-23 原文

struct A { A(int);};
struct B { explicit B(A); B(const B&);};
B b({0}); 

我问了一个问题Overload resolution gets different result between gcc and clang和@Johannes Schaub - litb 解释了活跃的规则。但是我对13.3.3.1.4 Reference binding还有一些疑问。

N4527 13.3.3.1.5 [over.ics.list] p1 和 p8

1 When an argument is an initializer list (8.5.4), it is not an expression and special rules apply for converting it to a parameter type.

8 Otherwise, if the parameter is a reference, see 13.3.3.1.4.

13.3.3.1.4 [over.ics.ref] p1 和 p2

1 When a parameter of reference type binds directly (8.5.3) to an argument expression, the implicit conversion sequence is the identity conversion, unless the argument expression has a type that is a derived class of the parameter type, in which case the implicit conversion sequence is a derived-to-base Conversion (13.3.3.1). [ Example... ]

If the parameter binds directly to the result of applying a conversion function to the argument expression, the implicit conversion sequence is a user-defined conversion sequence (13.3.3.1.2), with the second standard conversion sequence either an identity conversion or, if the conversion function returns an entity of a type that is a derived class of the parameter type, a derived-to-base Conversion.

2 When a parameter of reference type is not bound directly to an argument expression, the conversion sequence is the one required to convert the argument expression to the underlying type of the reference according to 13.3.3.1. Conceptually, this conversion sequence corresponds to copy-initializing a temporary of the underlying type with the argument expression. Any difference in top-level cv-qualification is subsumed by the initialization itself and does not constitute a conversion.

问题一:“参数表达式”是否包括“初始化列表”?请参阅上面的 13.3.3.1.5 [over.ics.list] p1 粗体短语和

1.3.2 [defns.argument]

argument

<function call expression> expression in the comma-separated list bounded by the parentheses (5.2.2)



8.5 [dcl.init] p17

17 The semantics of initializers are as follows. The destination type is the type of the object or reference being initialized and the source type is the type of the initializer expression. If the initializer is not a single (possibly parenthesized) expression, the source type is not defined.

(17.1) — If the initializer is a (non-parenthesized) braced-init-list, the object or reference is list-initialized (8.5.4).

(17.2) — If the destination type is a reference type, see 8.5.3.

8.5.3 [dcl.init.ref] p5

A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows:

[...]

(5.2.2.2) — Otherwise, a temporary of type “cv1 T1” is created and copy-initialized (8.5) from the initializer expression. The reference is then bound to the temporary.

[...]

除了最后一种情况(即从初始化表达式创建和初始化一个临时对象)之外的所有情况下, 据说引用直接绑定(bind)到初始化表达式。

问题2:“直接绑定(bind)”是否包括初始化器为初始化器列表的情况?换句话说,当初始化器是一个初始化器列表时,我们可以使用“直接绑定(bind)”吗?

注意:“直接绑定(bind)”是 8.5.3 中的定义,由 8.5 p17.1 引用,“初始化程序是花括号初始化列表”是 8.5.4 中的定义,由 8.5 p17.2 引用

//case 5.2.1.2
struct X{};

struct Y{Y(X);};
const Y& y1 = X();     // bind directly
const Y& y2 = {X()};   // bind directly or not?

struct Z{operator X();};
const X& x1 = Z();     // bind directly
const X& x2 = {Z()};   // bind directly or not?

//case 5.2.2.1
struct A{operator int();};
const int& a1 = A();   // bind directly
const int& a2 = {A()}; // bind directly or not?

struct B{B(int);};
const B& b1 = 1;       // bind directly
const B& b2 = {1};     // bind directly or not?

//csse 5.2.2.2
int i3 = 2;
double&& rrd3 = i3;    // not bind directly

struct A { A(int);};
struct B { explicit B(A); B(const B&);};
B b({0}); // when overload resolution choose B(const B&) as a candidate,
          // {0} -> constB& bind directly or not? 


问题 3(主要问题):

当一个参数是一个初始化列表并且参数是一个引用时,13.3.3.1.5 [over.ics.list] p8 引用到 13.3.3.1.4 [over.ics.ref],但我不能查看有关初始化列表的参数的任何单词。我认为“直接绑定(bind)”和“参数”的定义与“初始化列表”无关。

当参数是初始化列表且参数是引用时,您能解释一下重载决议是如何工作的吗?

注意:这三个问题是相关的。当您回答第三个问题时,您将回答第一个和第二个问题。

struct A { A(int);};
struct B { explicit B(A); B(const B&);};
B b1(0); //when overload resolution choose B(const B&) as a candidate,
         //0 -> const B& binds directly
         //13.3.3.1.4 [over.ics.ref] p1 "If the parameter binds directly..."
A a;
B b2(a)  //when overload resolution choose B(const B&) as a candidate,
         //a -> const B& binds directly
         //13.3.3.1.4 [over.ics.ref] p1 "If the parameter binds directly..."
B b3({0})//when overload resolution choose B(const B&) as a candidate,
         //{0} -> const B& binds directly or not?
         //if it is not bound directly, 13.3.3.1.4 [over.ics.ref] p2
B b3({a})//when overload resolution choose B(const B&) as a candidate,
         //{a} -> const B& binds directly or not?
         //if it is not bound directly, 13.3.3.1.4 [over.ics.ref] p2

最佳答案

我们只是有一个缺陷,报告为 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1536 (我刚刚发现,之前在写其他答案时并没有意识到该报告)。

按照 over.ics.ref 完全不可知的初始化列表的解释,并且正在谈论创建的临时对象(由 decl.init.list 创建的)绑定(bind)到引用,这对我来说似乎有问题。特别地,over.ics.list 表示 over.ics.ref 将委托(delegate)给 over.ics.list 来初始化临时文件,这表明 over.ics.ref 在创建临时文件之前已经处于事件状态(也有一些情况decl.init.list,其中没有创建临时文件)。此外,从 { } ClassType& 应该是用户定义的转换,但在考虑与初始化列表参数隔离的转换时,临时右值将直接由引用绑定(bind)。

关于c++ - 当参数是初始化列表且参数是引用时的重载解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33074102/

有关c++ - 当参数是初始化列表且参数是引用时的重载解析的更多相关文章

  1. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  2. ruby-on-rails - 未初始化的常量 Psych::Syck (NameError) - 2

    在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到ruby​​gems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby - 用逗号、双引号和编码解析 csv - 2

    我正在使用ruby​​1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\

  5. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  6. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  7. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  8. ruby - RVM 使用列表[0] - 2

    是否有类似“RVMuse1”或“RVMuselist[0]”之类的内容而不是键入整个版本号。在任何时候,我们都会看到一个可能包含5个或更多ruby的列表,我们可以轻松地键入一个数字而不是X.X.X。这也有助于rvmgemset。 最佳答案 这在RVM2.0中是可能的=>https://docs.google.com/document/d/1xW9GeEpLOWPcddDg_hOPvK4oeLxJmU3Q5FiCNT7nTAc/edit?usp=sharing-知道链接的任何人都可以发表评论

  9. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

  10. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

随机推荐