class Namespace::Class;
Зачем мне это делать?
namespace Namespace {
class Class;
}
Используя VC ++ 8.0, компилятор выдает:
ошибка C2653: «Пространство имен»: это не имя класса или пространства имен
Я предполагаю, что проблема здесь в том, что компилятор не может определить, Namespace
является ли класс или пространство имен? Но почему это важно, так как это всего лишь предварительное заявление?
Есть ли другой способ объявить вперед класс, определенный в некотором пространстве имен? Синтаксис выше выглядит так, будто я «заново открываю» пространство имен и расширяю его определение. Что если в Class
действительности не определены Namespace
? Не приведет ли это к ошибке в какой-то момент?
c++
namespaces
Ён ли
источник
источник
A::B
A
Namespace
это класс или пространство имен. Только не приближайтесь к намеку о возможности предположительно начать языковую войну за синтаксис.Ответы:
Потому что ты не можешь. В языке C ++ полностью определенные имена используются только для ссылки на существующие (то есть ранее объявленные) сущности. Они не могут быть использованы для введения новых лиц.
И это на самом деле «повторное открытие» пространство имен , чтобы объявить новые объекты. Если
Class
впоследствии класс будет определен как член другого пространства имен - это совершенно другой класс, который не имеет ничего общего с тем, который вы объявили здесь.Как только вы дойдете до определения предварительно объявленного класса, вам не нужно снова «открывать» пространство имен. Вы можете определить его в глобальном пространстве имен (или в любом пространстве имен, включающем ваше
Namespace
) какПоскольку вы имеете в виду сущность, которая уже была объявлена в пространстве имен
Namespace
, вы можете использовать полное имяNamespace::Class
.источник
Вы получаете правильные ответы, позвольте мне попробовать переформулировать:
class Namespace::Class;
Вы должны сделать это, потому что термин
Namespace::Class
говорит компилятору:Но компилятор не знает, о чем вы говорите, потому что он не знает ни одного именованного пространства имен
Namespace
. Даже если было названо пространство именNamespace
, как в:это все равно не сработает, потому что вы не можете объявить класс в пространстве имен вне этого пространства имен. Вы должны быть в пространстве имен.
Таким образом, вы можете объявить класс в пространстве имен. Просто сделай это:
источник
Я полагаю, что по той же причине вы не можете объявить вложенные пространства имен за один раз:
и вы должны сделать это:
источник
Непонятно, что представляет собой тип объявленной вперед переменной. Предварительная декларация
class Namespace::Class;
может означатьили
источник
Есть много отличных ответов об обосновании, запрещающем это. Я просто хочу предоставить скучную стандартную оговорку, которая специально запрещает это. Это верно для C ++ 17 (n4659).
Рассматриваемый абзац - [class.name] / 2 :
Выше определено, что составляет предварительное объявление (или объявление класса). По сути, он должен быть одним из
class identifier;
,struct identifier;
илиunion identifier;
где идентификатор - это общее лексическое определение в [lex.name] :Что является производством общей схемы, с которой
[a-zA-Z_][a-zA-Z0-9_]*
мы все знакомы. Как видите, это исключает возможностьclass foo::bar;
быть допустимым предварительным объявлением, посколькуfoo::bar
не является идентификатором. Это полностью определенное имя, что-то другое.источник