Причина, по которой нельзя разрешать предварительные объявления вложенного класса? - PullRequest
7 голосов
/ 13 июля 2011

Пример:

// can't forward declare with class Foo::Bar

// actual class
class Foo
{
public:
    class Bar // or enum Bar
    {
    }
};

Я принимаю, что это не разрешено в соответствии с текущими стандартами C ++, но я не смог придумать вескую причину, чтобы этого не допустить, хотя, особенно с C ++ 0x, мы теперь можем пересылать объявления перечислений. Я думаю, что аргумент против этого будет, если мы объявим вложенный класс, который оказывается закрытым, это не будет разрешено. Но это не было бы слишком отличным, чтобы сказать вперед, объявив класс в пространстве имен, а затем объявив его вложенным классом внешнего класса. Компилятор просто выдаст ошибку (возможно, сообщение об ошибке в строке предыдущего объявления не соответствует этому объявлению).

Так почему же тогда это не разрешено?

Другими словами (Джеймсом МакНеллисом): «почему класс Foo :: Bar; без определения Foo или Bar не допускается?»

** Учитывая, что комитет по стандартам C ++ признал преимущество использования предварительных объявлений для уменьшения зависимостей и времени компиляции путем введения прямого объявления перечислений в C ++ 0x, несомненно, это часть того же, не так ли?

Ответы [ 3 ]

9 голосов
/ 13 июля 2011

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

Аргумент в пользу того, что не следует объявлять перечисления (enum x;), заключался просто в том, чтокомпилятор не может выбрать правильный размер для перечисляемых переменных, пока не увидит, сколько значений существует.Эта проблема была решена путем разрешения you выбрать для компилятора (enum x : int;).Это также было реализовано и показано, что оно работает должным образом, прежде чем войти в стандарт.

См. http://www.open -std.org / jtc1 / sc22 / wg21 / docs /apers / 2008 / n2764.pdf

3 голосов
/ 13 июля 2011

Вложенные классы наверняка МОГУТ быть объявлены вперед:

class Foo
{
public:
    class Bar;
};

class Foo::Bar
{
};
2 голосов
/ 13 июля 2011

Как вы могли бы объявить вложенный класс?Чтобы сделать это, вы должны объявить класс, в который он вложен. Как только вы пойдете:

class ClassName {

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

Перечисления по причине only не могут быть заранее объявлены до сих пор, потому что их размер был определених счетчиками.Вот почему вы должны указать им явный размер, чтобы затем объявить их.

...