A question about template class forwarding definition

Hi,

I have a class forwarding definition issue. For the following small test case, gcc can build pass, but clang(trunk) will build fail.

You can’t use a forward declaration in contexts where object’s size must be known. Note that your member function g is fine as B only appears in the parameter list. It can also appear as return type. Declaring pointers is also fine but the moment you try to construct an actual object the type will have to be fully defined. I think this is a gcc bug.

Hi,

I have a class forwarding definition issue. For the following small test
case, gcc can build pass, but clang(trunk) will build fail.

====================================

template<class T> class B;

template<class T>
class A
{
  public:
    void f(void) const { B<double> e; g(e); }
    void g(B<double> &e) const;
};

template<class T>
class B
{
public:
  T x[9];

  B() {
    for(int i=0;i<9;i++) x[i]=0;
  }
};
$ g++ -std=c++03 -c tt.cc
$ clang++ -std=c++03 -c tt.cc
tt.cc:7:36: error: implicit instantiation of undefined template 'B<double>'
    void f(void) const { B<double> e; g(e); }
                                   ^
tt.cc:1:25: note: template is declared here
template<class T> class B;
                        ^
1 error generated.

====================================

Is this bug in clang?

If not, how should I write the forwarding declaration for class B, and why
gcc can pass?

This is one of those cases where a compiler isn't required to diagnose the
fact that your program is invalid (the standard wording is "invalid, no
diagnostic required").

The particular issue is that B<double> is not a dependent name - so the
compiler can resolve it at template (A<T>) declaration time, without having
to wait for an instantiation to realize that B<double> is not defined.

That's my understanding at least.