Вывод типов

Я пытаюсь понять вывод типов, просматривая «Эффективный современный C++» Скотта Мейера.

Рассмотрим фрагмент кода ниже:

template<typename T>
void f(const T& param); // param is now a ref-to-const; paramType is const T&

int x = 27; // as before
const int cx = x; // as before
const int& rx = x; // as before

f(x); // T is int, param's type is const int&
f(cx); // T is int, param's type is const int&
f(rx); // T is int, param's type is const int&

Он говорит, что, поскольку paramType является ссылкой, мы можем выполнить двухэтапную процедуру, чтобы вывести тип T:

  1. Игнорировать ссылки (если есть) в expr (т. е. x, cx и rx)
  2. Шаблон соответствует типу expr и paramType

Теперь, когда cx является const int:

cx -> const целое

paramType -> ссылка на const int

Итак, согласно упомянутой логике, не должно ли T быть const int из-за сопоставления с образцом (а не только int)? Я понимаю, что constness cx был передан paramType, но то, что он говорит, неверно? Является ли эта двухэтапная процедура, о которой он упомянул, несоблюдением эмпирического правила? Как ты это делаешь?

Спасибо!


person Community    schedule 27.03.2017    source источник
comment
Вы что-то искажаете. Что такое paramType?   -  person Kerrek SB    schedule 28.03.2017
comment
@KerrekSB, это const T&. Я включил это в комментарии (во 2-й строке кода).   -  person    schedule 28.03.2017
comment
Не используйте комментарии. Обращайтесь только к вещам в реальном коде. Я понятия не имею, что означает комментарий. Вместо этого произнесите тип param.   -  person Kerrek SB    schedule 28.03.2017
comment
Легче обернуться, если вы интерпретируете const T& как const ссылку на T вместо ссылки на const T; сущность const может связываться только со ссылкой const, но сущности без cv могут связываться как со ссылками const, так и со ссылками не const.   -  person Justin Time - Reinstate Monica    schedule 28.03.2017
comment
В большинстве случаев они фактически идентичны (ссылка const на int фактически рассматривает int как const, независимо от того, так это или нет), но не всегда (например, при работе со ссылками на указатели; const int*& — это не-cv ссылка на const int*, а int* const& — это const ссылка на int*, что идентично синтаксису разница между указателем на const int (const int*) и указателем const на int (int* const)).   -  person Justin Time - Reinstate Monica    schedule 28.03.2017


Ответы (2)


В своей книге Скотт использует это "обозначение":

template<typename T>
void f(ParamType param); // where `ParamType` depends on T

Итак, давайте выполним сопоставление с образцом для ParamType, когда param равно const int. У нас есть:

const T & <----> const int // <----> is symbolic notation for pattern matching

Таким образом, T выводится как int, следовательно, ParamType равно const int&.

person vsoftco    schedule 27.03.2017
comment
Благодарю вас! Это то, что я искал. Однако один вопрос - вы упоминаете в комментариях where ParamType depends on T - а не наоборот? - person ; 28.03.2017
comment
@user6490375 user6490375 Нет, ParamType — это функция типа T, например const T*. - person vsoftco; 28.03.2017
comment
Я неправильно понял сопоставление с образцом как нечто вроде пересечения множества. (Может быть, потому что я понял, что все, что совпадает, является частью шаблона). Итак, я пришел к выводу, что T равно const int. - person ; 28.03.2017

Когда cx равно const int, тогда T выводится как int, так что const T& param равно const int& param, т. е. param имеет тип const int&.

person Kerrek SB    schedule 27.03.2017
comment
Спасибо за ваш ответ. Однако я ищу ответ с учетом двух шагов, упомянутых в книге. Я считаю, что понимание этих двух шагов было бы полезно для вывода сложных типов. - person ; 28.03.2017