C ++ 0x: разрешение перегрузки - PullRequest
3 голосов
/ 19 июля 2011

В Standard-Text есть пример в 8.5.4 (3) Инициализация списка [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, но я ссылаюсь на разрешение перегрузки здесь).

Принимая во внимание, что Скотт Мейерс в своем выступлении / слайдах рассказывает другую историю:всегда предпочтительнее других типов:

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 -конструкторами?Или здесь другая проблема?

Как перегрузка решается в обоих случаях?Если оба они верны, что мне здесь не хватает?

Редактировать / Уточнить после Керика Комментарий: я чувствую, что два примера противоречат друг другу:

  • В Std приведен пример, где const char* преобразуется в string, что не соответствует предоставленному initializer_list<int> и, следовательно, предоставленному "обычному" const string& -c 'Используется tor.
  • Пример Скотта инициализируется с {double, double}, когда intializer_list<int> -c'or доступен и поэтому выбран, потому что список, утверждает он, предпочтителен.Таким образом, предоставляемый (double, double) -c'or никогда не выбирается при инициализации таким способом.

Конечно, Std всегда верен, но, возможно, я неправильно применю пример.Пример Std содержит &, что, по моему мнению, не имеет отношения к моему вопросу, но, возможно, я ошибаюсь.

Слайты Скотта довольно недавние, и я не вижу, что соответствующий раздел (s) в стандарте изменились в этом отношении (хотя трудно все охватить, потому что это несколько "широко распространено": -)

Edit-2 : я получилписьмо от самого Скотта о том, что в Стандарте было позднее изменение *1049*, которое не было включено в слайды.

1 Ответ

5 голосов
/ 19 июля 2011

В соответствии с N3291, рабочим проектом от 5 апреля 2011 года, в списки инициализаторов были внесены некоторые изменения, поэтому слайды Скотта Мейера могут быть из старых данных.

Согласно разделу 13.3.1.7 (так близко к 1337):

  • Первоначально функции-кандидаты являются конструкторами списка инициализаторов (8.5.4) класса T, а список аргументов состоит из списка инициализаторов как единственного аргумента
  • Если жизнеспособный конструктор списка инициализаторов не найден, разрешение перегрузки выполняется снова, где все функции-кандидаты являются конструкторами класса T, а список аргументов состоит из элементов списка инициализатора.

Так что он предпочитает списки инициализаторов. Но если список инициализаторов не совпадает, то он проверит обычные конструкторы, чтобы увидеть, совпадают ли они.

Далее говорится, что если список инициализатора пуст, то используется конструктор по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...