C++0x:过载解析

发布于 2024-11-25 09:26:22 字数 1710 浏览 2 评论 0原文

在标准文本中有一个例子 8.5.4 (3) List-initialization [dcl.init.list]

struct S {
    S(std::initializer_list<double>);  // #1
    S(const std::string&);             // #2
};
const S& r1 = { 1, 2, 3.0 };  // OK: invoke #1
const S& r2 { "Spinach" };    // OK: invoke #2 !!!

(该示例是关于 ref-to-temp 的,但我参考了此处的重载解析)。

而 Scott Meyers 在他的演讲/幻灯片中讲述了一个不同的故事:

std::initializer_list 参数始终优先于其他类型:

class Widget {
public:
    Widget(double value, double uncertainty);           // #1
    Widget(std::initializer_list<std::string> values);  // #2
};
double d1, d2;
Widget w1 { d1, d2 }; // tries to call #2; fails because
                      // no double ⇒ string conversion

示例略有不同,但它们不是同一件事吗?何时以及如何使用 initializer_list 构造函数进行重载决策?或者这里有不同的问题?

这两种情况下的重载是如何决定的?如果两者都是正确的,我在这里错过了什么?

编辑/澄清根据Keric的评论:我的感觉是,这两个例子相互矛盾:

  • 标准给出了一个示例,其中将 const char* 转换为 string,它与提供的 initializer_list 不匹配,因此提供的 "正常” 常量使用 string&-c'tor。
  • Scott 的示例在 intializer_list-c'tor 可用并因此被选择时使用 {double, double} 进行初始化,因为他认为该列表是首选。因此,以这种方式初始化时,永远不会选择还提供的 (double, double)-c'tor。

当然,标准总是正确的,但也许我错误地应用了这个例子。 Std 示例中有 & ,我认为这与我的问题无关,但也许我错了。

斯科特的幻灯片是最近的,我看不到标准中的相关部分已经在这方面发生了变化(尽管,很难将所有内容纳入范围,因为它有点“广泛传播”:-)

Edit-2:我收到了 Scott 本人发来的邮件,其中有一个 标准中的最新更改尚未纳入幻灯片。

In the Standard-Text there is an example in 8.5.4 (3) List-initialization [dcl.init.list]

struct S {
    S(std::initializer_list<double>);  // #1
    S(const std::string&);             // #2
};
const S& r1 = { 1, 2, 3.0 };  // OK: invoke #1
const S& r2 { "Spinach" };    // OK: invoke #2 !!!

(the example is about the ref-to-temp, but I refer to the overload resolution here).

Whereas Scott Meyers in his talk/slides tells a different story:

std::initializer_list parameters are always preferred over other types:

class Widget {
public:
    Widget(double value, double uncertainty);           // #1
    Widget(std::initializer_list<std::string> values);  // #2
};
double d1, d2;
Widget w1 { d1, d2 }; // tries to call #2; fails because
                      // no double ⇒ string conversion

The examples are slightly different, but aren't those about the same thing? When and how overload resolution with initializer_list-constructors happens? Or is there a different issue here?

How is the overloading decided in both cases? If both are correct, what do I miss here?

Edit/Clarification upon Keric's Comment: My feeling ist, that the two examples contradict each other:

  • The Std gives an example where a const char* is converted to a string, which does not match the provided initializer_list<int> and therefore the provided "normal" const string&-c'tor is used.
  • Scott's example initializes with {double, double} when an intializer_list<int>-c'tor is available and therefore chosen, because the list, he argues, is preferred. Thus the also provided (double, double)-c'tor is never chosen when initialized this way.

Of course, the Std is always right, but maybe I apply the example wrongly. The Std example has & in it, that I don't think are relevant for my question, but maybe I am wrong.

Scott's slides are quite recent, and I can not see that the relevant section(s) in the Std have changed to that respect (although, it's difficult to get everything into scope, because it's somewhat "widely spread" :-)

Edit-2: I got a mail from Scott himself that there was a late change in the Standard that had not been incorporated into the slides.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦与时光遇 2024-12-02 09:26:22

根据 2011 年 4 月 5 日的工作草案 N3291,初始化器列表发生了一些变化,因此 Scott Meyer 的幻灯片可能来自旧数据。

根据第 13.3.1.7 节(非常接近 1337):

  • 最初,候选函数是类 T 的初始化器列表构造函数 (8.5.4),参数列表由初始化器列表作为单个参数组成
  • 如果没有找到可行的初始化器列表构造函数,则再次执行重载决策,其中候选函数是类 T 的所有构造函数,参数列表由初始化器列表的元素组成。

所以它确实更喜欢初始化程序列表。但如果初始值设定项列表不匹配,那么它将检查常规构造函数以查看它们是否匹配。

它接着说,如果初始值设定项列表为空,则使用默认构造函数。

Pursuant to N3291, the Working Draft from April 5, 2011, there has been a few changes to initializer lists, so Scott Meyer's slides may be from old data.

According to section 13.3.1.7 (so close to 1337):

  • Initially, the candidate functions are the initializer-list constructors (8.5.4) of the class T and the argument list consists of the initializer list as a single argument
  • If no viable initializer-list constructor is found, overload resolution is performed again, where the candidate functions are all the constructors of the class T and the argument list consists of the elements of the initializer list.

So it does prefer initailizer lists. But if the initializer list doesn't match, then it will check the regular constructors to see if they match.

It goes on to say that if the initializer list is empty, then the default constructor is used.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文