Ниже код работает нормально:
template<typename T> class X {};
class A; // line-1
void foo(); // line-2
int main ()
{
X<A> vA;
}
class A {};
void foo() {}
Пусть строка-1 и строка-2 перемещены внутрь main()
, Функция не влияет, но class A
предварительная декларация не работает и дает ошибка компилятора:
ошибка: аргумент шаблона для
template<class T> class X
использует местный
типmain()::A
То, что вы можете наблюдать, происходит потому, что в C ++ вы можете определять классы внутри функций.
Итак, если вы разместите class A;
в main
вы объявляете класс в области действия этой функции (т.е. class main::A
), не в глобальном масштабе (class A
).
Таким образом, вы, наконец, объявляете объект типа X с аргументом шаблона неопределенного класса (X<main::A>
).
ошибка: аргумент шаблона для шаблона класса X использует локальный тип main () :: A
Это настоящая проблема — использование локального типа. В C ++ 03 нельзя использовать локальные типы в качестве аргументов шаблона, потому что никто не понял, как название результирующие типы.
Что делать, если у вас есть несколько class A
в нескольких перегруженных функциях (опять же с тем же именем) — будет X<A>
Тогда будет один и тот же тип или разные типы? Как бы вы их отличали?
В C ++ 03 стандарт прошел это и сказал: «Не делай этого!».
Проблема была решена в C ++ 11, решив, что X<A>
используя локальный тип A
будет так же, как если бы A
был объявлен в анонимном пространстве имен вне функции, как
namespace
{
class A
{ };
}
int main()
{
X<A> vA;
}
Итак, с новым компилятором (или с использованием -std=cpp11
вариант), вы можете использовать локальный класс, и мы также знаем, что это значит.
Однако объявление типа forward внутри функции по-прежнему не означает то же самое, что и объявление forward в другой области видимости. Они просто будут разных типов.