Как эти коды связаны друг с другом? - PullRequest
0 голосов
/ 20 сентября 2019

Я читаю статью Скотта Мейерса об универсальных ссылках, и я не совсем понимаю эту часть:

Третий контекст, сворачивающий ссылки, - это формирование и использование typedef.,Учитывая этот шаблон класса

template<typename T>
class Widget {
     typedef T& LvalueRefType;
     ...
};

и это использование шаблона,

Widget<int&> w;

экземпляр класса будет содержать этот (недопустимый) typedef:

typedef int& & LvalueRefType;

Свертывание ссылок сокращает его до этого допустимого кода:

typedef int& LvalueRefType;

Тип int используется, но шаблон для типа Widget.Как коды связаны друг с другом?ТИА.

1 Ответ

0 голосов
/ 21 сентября 2019

Эта часть статьи предполагает некоторое знакомство с шаблонами.Если вы не знакомы с терминологией шаблонов, может быть лучше изучить шаблоны, прежде чем пытаться понять этот «контекст свертывания ссылок».Или, может быть, было бы достаточно короткого перерыва?Я буду ошибаться в объяснении.

template<typename T>
class Widget {
     typedef T& LvalueRefType;
     ...
};

Это шаблон класса .Это план для определения классов, без определения.Перед использованием этого проекта необходимо указать тип для использования в проекте (в данном примере это T).

Widget<int&> w;

Это определяет переменную (w)чей класс генерируется с использованием плана.Помните, что план требует, чтобы тип был указан?В этом примере указывается int& в качестве этого типа.Почему int&?* пожимает плечами * Это тот тип, который хочет использовать Скотт Мейерс.Авторы могут решать произвольные вещи, как это.Не беспокойтесь об этом.

Так что же происходит, когда вы указываете тип?План копируется, и в копии производятся замены.В этом случае каждый экземпляр T заменяется на int&, давая конкретное определение класса.Это определение класса называется экземпляром класса с именем Widget<int&>.Вы не увидите это определение нигде;это то, что компилятор работает.Тем не менее, если вы хотите быть немного слабоватыми с правильным синтаксисом C ++, следующее показывает, как будет выглядеть определение класса:

class Widget<int&> {
     typedef int& & LvalueRefType;
     ...
};

В строке typedef, T изшаблон был заменен на int&.Я также добавил пробел после него, чтобы отделить его от амперсанда, который следует за ним (T& и T & означают одно и то же).Это приводит нас к следующей строке кода из статьи:

typedef int& & LvalueRefType;

Выглядишь знакомо?Весь смысл установки состоял в том, чтобы получить этот странно выглядящий код, который использует ссылку на ссылку (на int).Теперь мы переходим к разрушению ссылок.Вы не можете взять ссылку на ссылку, но авторы языка не хотели автоматически лишать законной силы такой тип использования шаблона.Так что где-то в спецификации языка есть пункт, в котором говорится, что в подобной ситуации компилятор должен настроить экземпляр класса, избавившись от одного из амперсандов в проблемной строке.

Когда вы удаляете амперсанд изстрока, с которой мы имеем дело, вы получите последнюю строку кода, которую вы цитировали.Это эффективно то, что компилятор будет использовать, когда он генерирует определение Widget<int&>.

typedef int& LvalueRefType;

Так что это довольно быстрый и неполный взгляд на шаблоны, с достаточной детализацией для (надеюсь) разобраться в этой части статьи.

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