Недавно я увидел странную особенность C ++: введенное имя класса .
class X { };
X x1;
class X::X x2; // class X::X is equal to X
class X::X::X x3; // ...and so on...
Но я не могу понять, почему эта функция необходима. Есть ли практика, которая требует этой функции?
И я слышал, что эта функция не существовала в старом C ++. Тогда когда это было введено? C ++ 03? C ++ 11?
Ответы:
Внедренное имя класса означает, что
X
оно объявлено как член классаX
, так что поиск имени внутриX
всегда находит текущий класс, а не другой,X
который может быть объявлен в той же области действия, напримерЯвляется ли
create()
функция создания временногоX
объекта или вызов функцииX
? В области имен он будет вызывать функцию, поэтому цель injected-class-name состоит в том, чтобы гарантировать, что в телеX
имени всегда найдется сам класс (поскольку поиск имени начинается в собственной области видимости класса, прежде чем искать во вложении). объем).Это также полезно внутри шаблонов классов, где введенное имя класса можно использовать без списка аргументов шаблона, например, просто используя
Foo
вместо полного идентификатора шаблонаFoo<blah, blah, blah>
, поэтому легко ссылаться на текущую реализацию. См. DR 176 об изменениях между C ++ 98 и C ++ 03, которые прояснили это.Идея введенного имени класса была представлена в C ++ 98, но терминология была новой для C ++ 03.
C ++ 98 говорит:
Второе предложение было изменено DR 147, поэтому C ++ 03 говорит в [class] / 2:
Даже до C ++ 98 ARM имеет примерно эквивалентную формулировку, которая означает, что имя класса всегда можно использовать в теле класса для ссылки на сам класс:
источник