Возврат ссылки на форвард-объявленный тип (С++)

У меня есть метод класса, который возвращает ссылку на что-то. Когда я использую этот метод, если у меня есть только одно объявление вперед, я могу только скомпилировать, если я назначу вывод метода. Я действительно не понимаю, почему...

Здесь приведен упрощенный пример:

ClassA.h:

//Forward declare
class ClassB;

class ClassA
{
public:
    ClassA(void);
    ~ClassA(void);

    ClassB& Func();
};

ClassA.cpp:

#include "ClassA.h"

#include "ClassB.h"

ClassA::ClassA(void)
{}

ClassA::~ClassA(void)
{}

static ClassB c;

ClassB& ClassA::Func()
{
    return c;
}

ClassB.h:

#pragma once
class ClassB
{
public:
    ClassB(void) {};
    ~ClassB(void) {};
};

Теперь, если я вызываю ClassA::Func без присвоения возвращаемого значения (при наличии только прямого объявления ClassB), он не будет компилироваться:

main.cpp:

#include "ClassA.h"

int main(void)
{
    ClassA a;

    a.Func(); //error C2027: use of undefined type 'ClassB'

    return 0;
}

Если я использую эту строку вместо этого, она работает: ClassB& b = a.Func();

Что здесь происходит? Зачем компилятору нужно знать размер ClassB или его методы, когда возвращаемое значение нигде не назначено?

Я компилирую это с помощью VisualStudio 2010 SP1.

Ответ 1

Похоже на "ограничение" компилятора, страница MSDN для C2027 говорит:

Можно объявить указатель на объявленный, но undefined тип. Но Visual С++ не позволяет ссылаться на тип undefined.

Следующий образец генерирует C2027.

И дает следующий пример:

class A;
A& CreateA();

class B;
B* CreateB();

int main() {
   CreateA();   // C2027
   CreateB();   // OK
}

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