Почему прямое объявление класса не допускается в области действия функции?

Ниже код работает нормально:

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

3

Решение

То, что вы можете наблюдать, происходит потому, что в C ++ вы можете определять классы внутри функций.
Итак, если вы разместите class A; в mainвы объявляете класс в области действия этой функции (т.е. class main::A), не в глобальном масштабе (class A).

Таким образом, вы, наконец, объявляете объект типа X с аргументом шаблона неопределенного класса (X<main::A>).

4

Другие решения

ошибка: аргумент шаблона для шаблона класса 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 в другой области видимости. Они просто будут разных типов.

2

По вопросам рекламы [email protected]