Двофазний пошук - потрібне пояснення


74

Що означає, що компілятор використовує двофазний пошук для компіляції класу шаблону?


1
@Nawaz Я чув лише про двофазний пошук, чи чогось мені не вистачає?
smallB

2
Коротку та корисну статтю на цю тему можна знайти за адресою blog.llvm.org/2009/12/dreaded-two-phase-name-lookup.html
Нікола

Відповіді:


67

Шаблони компілюються (принаймні) двічі:

  1. Без Instantiation сам код шаблону перевіряється на синтаксис.
    Наприклад: будь-які синтаксичні помилки, такі як ;тощо.

  2. Під час створення екземпляра (коли відомий точний тип), код шаблону перевіряється ще раз, щоб переконатися, що всі виклики дійсні для цього конкретного типу.
    Напр .: Шаблон може, у свою чергу, викликати функції, які можуть бути відсутні для цього конкретного типу.

Це називається двофазним пошуком.


49
Також зверніть увагу, що пошук для незалежних імен виконується на першому етапі, тоді як пошук імен, які залежать від параметра шаблону, виконується на другому етапі. Важливість полягає в тому, що якщо ви телефонуєте sqrt(1), його sqrtпотрібно оголосити до визначення шаблону. Але якщо ви викликаєте sqrt(t), де tекземпляр типу, який є параметром шаблону, тоді його sqrtне потрібно бачити, доки шаблон не буде створений. MSVC раніше не робив цього правильно: все ще може не все, що я знаю.
Steve Jessop

14
У будь-якому випадку, саме тому це називається двофазним пошуком , на відміну від просто двофазної компіляції чи чогось іншого. Перший етап повинен виконувати більше, ніж просто перевіряти синтаксис, але у MS виникли певні труднощі з реалізацією першого етапу пошуку, тому вони просто зробили все це під час створення: stackoverflow.com/questions/6273176/…
Стів Джессоп,

3
Історичне зауваження: Я використовував компілятор, який мав фазу підрахунку фігурних дужок та фазу компіляції. Даний IOW template <class T> class C { put really anything here & ~ - (but nothing unbalanced and no 8-bit char outside string literal) }буде прийнятий, якщо Cніколи не було інстанцій! Це було більше десяти років тому.
curiousguy

2
Для допитливих це уривок із шаблонів C ++: Повне керівництво .
legends2k

2
На додаток до коментаря @ SteveJessop щодо залежних імен, варто також зазначити, що це "пошук, залежний від аргументу", який відбувається із залежними іменами. Це означає, що ::sqrt(::NS::A)він не буде знайдений, оскільки додатковий пошук буде відбуватися в, ::NSа не в ::. Останній момент полягає в тому, що сфера дії псевдоніма, typedef або з використанням, не буде шукатись, лише область дії самого алізованого типу.
Річард Корден,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.