Чому існує введене ім’я класу?


147

Нещодавно я побачив дивну особливість 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?


Друже, ти можеш подивитися на Skype? Я не можу до вас дійти
Ірінель Іован

Відповіді:


162

Ім'я введеного класу означає, що Xоголошується членом X, тому пошук імені всередині Xзавжди знаходить поточний клас, а не інший, Xякий може бути оголошений в тій же області, що додається, наприклад

void X() { }
class X {
public:
  static X create() { return X(); }
};

Чи create()функція створює тимчасовий Xоб'єкт або викликає функцію X? У області простору імен він би викликав функцію, тому мета введеного класу-імені полягає в тому, щоб забезпечити, щоб всередині тіла 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 має приблизно еквівалентне формулювання, що означає, що ім'я класу завжди можна використовувати в тілі класу для позначення самого класу:

Ім'я класу можна використовувати як ім'я класу навіть у списку членів самого специфікатора класу.

  • Наприклад,

    class link { link* next; };


2
У мене це запитують досить часто, але ніколи не вдалося створити простий приклад, що вказував би на проблему. Так +1 Для прикладу.
dhein

1
Це можна чітко побачити, якщо ви запустите clang ++ your_program.cpp -Xclang -ast-dump і побачите свій клас, а потім введений дочірній вузол класу.
xaxxon
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.