Const в авто типе удержания

Я читаю Эффективный современный C ++ от Скотта Мейерса. Элемент 1 содержит следующий пример:

template<typename T>
void f(T& param);       // param is a reference
int x = 27;             // x is an int
const int cx = x;       // cx is a const int
f(cx);                  // T is const int,
// param's type is const int&

В пункте 3 появляется следующий пример:

Widget w;
const Widget& cw = w;
auto myWidget1 = cw;             // auto type deduction:
// myWidget1's type is Widget

На основании пункта 1 я ожидал myWidget1тип быть const Widget, Я что-то пропустил?

1

Решение

В большинстве случаев auto следует правилам вывода аргументов шаблона:

§ 7.1.6.4 [dcl.spec.auto] / p6:

После того, как тип описатель-идентификатор был определен согласно 8.3, тип объявленной переменной
с использованием описатель-идентификатор определяется по типу его инициализатора с использованием правил для аргумента шаблона
вычет. Позволять T быть типом, который был определен для идентификатора переменной d, получать P от T от
заменяя вхождения auto либо с новым параметром шаблона изобретенного типа U или, если инициализатор
это приготовился-INIT-лист (8.5.4), с std::initializer_list<U>, Тип, выведенный для переменной d затем выводится A определяется с использованием правил вывода аргументов шаблона из вызова функции (14.8.2.1).

§ 14.8.2.1 [temp.deduct.call] / p2:

Если P не является ссылочным типом:

  • […]
  • Если A это cv-квалифицированный тип, cv-квалификаторы верхнего уровня Aтип игнорируются для вывода типа.

Если ты хочешь myWidget1 быть типом const Widget&, он должен быть объявлен как ссылочный тип, например:

auto& myWidget1 = cw;
//  ^

DEMO

3

Другие решения

auto myWidget1 = cw; следует третьему правилу вывода типа аргумента шаблона в книге Мейерса, который передается по значению.
Когда вы передаете по значению, cv-qualifiers и ссылки игнорируются, потому что вы получаете новую копию объекта, поэтому вам не важно, был ли старый объект, с которого вы скопировали, константой или ссылкой.

1

По вопросам рекламы [email protected]