Эта часть статьи предполагает некоторое знакомство с шаблонами.Если вы не знакомы с терминологией шаблонов, может быть лучше изучить шаблоны, прежде чем пытаться понять этот «контекст свертывания ссылок».Или, может быть, было бы достаточно короткого перерыва?Я буду ошибаться в объяснении.
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;
Так что это довольно быстрый и неполный взгляд на шаблоны, с достаточной детализацией для (надеюсь) разобраться в этой части статьи.