Когда использовать разработанный спецификатор типа

Есть ли особенно веская причина, чтобы выбрать использование разработанного спецификатора типа? Например, при определенных обстоятельствах необходимо использоватьtemplate или жеtypename ключевые слова для устранения неоднозначности зависимогоtemplate или введите.

Но я не могу думать ни о каких примерах, где это могло бы произойти для чего-то такого, как перечисление. Возьмите следующий пример кода:

enum Foo { A,  B };

void bar(Foo foo);
void baz(enum Foo foo);

Почему я могу использовать синтаксисbaz() обеспечивает болееbar() (или наоборот)? Есть ли двусмысленный случай?

Ответы на вопрос(4)

Одной из веских причин выбрать использование разработанного спецификатора типа является переадресация объявленных структур или классов в заголовках. Учитывая заголовок, который определяет тип

// a.h
struct foo {};

Вы можете включить этот заголовок в прототип вашей функции

#include "a.h"
void foo(foo * ) ;

или используйте разработанный тип:

void foo(struct foo * ) ;

или, прямо вперед, объявляя, используя разработанный тип:

struct foo ;
void foo( foo * ) ;

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

Я понимаю, что C ++ 11 также разрешит такого рода прямые ссылки для enum, что в настоящее время не разрешено в компиляторах C ++ 01.

Решение Вопроса

Нет никаких причин использовать такие спецификаторы, если только вы не столкнулись с ситуацией, когда имя скрыто по имени другого типа. Например, вполне допустимо объявлять переменную с именемFoo после объявления enum, поскольку, говоря неформально, имена объектов и имена типов живут в независимых "пространствах имен" (см. 3.3 / 4 для более формальной спецификации)

enum Foo { A, B };

int Foo;

Послеint Foo декларация, вашbar декларация станет недействительной, а более сложнаяbaz декларация останется в силе.

Пример, который может подойти, - это когда у вас есть тип, а также нетипичный элемент с тем же именем. Используя разработанный спецификатор типа, вы можете явно запросить тип:

struct foo {};
void foo(struct foo) {}
int main() {
   struct foo f;
   foo(f);
}

Без разработанного спецификатора типа,foo вmain относится кvoid foo(struct foo)не к типуstruct foo, Я бы не хотел, чтобы это было в рабочем коде, но вы попросили только пример, где это имеет значение. То же самое может произойти, если тип и функция (или переменная) определены в разных пространствах имен, где не тип был найден ранее при поиске. Вы можете заменитьstruct сenum выше.

Разработанные спецификаторы типов необходимы для объявления пользовательских типов. Одним из вариантов использования является предварительное объявление ваших типов. В маловероятном случае, если у вас есть функция с тем же именем, что иenum вы видите в области видимости, вам может понадобиться использовать разработанный спецификатор типа в объявлении функции:

enum A { A_START = 0 };

void A(enum A a) {}

int main() {
   enum A a;
   A( a );
}

Ваш ответ на вопрос