Topic: Help! Template forward declaration


Author: "Bartosz Milewski" <bartoszm@halcyon.com>
Date: 1997/05/06
Raw View
It turned out that a simple forward declaration worked after all.
The line:
   template<class T> class Bar;
before the Foo template does the trick. As a matter of fact
this was the first thing I tried, but VC++ did not recompile
the affected file.

 [Moderator's note: this was followed by various complaints re VC++,
 but they're not relevant to this newsgroup, so I edited them out.
  -fjh.]

---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Stefan.Gartz@abc.se (Stefan Gartz)
Date: 1997/05/04
Raw View

BM> I have code in my program that has some circular template class
BM> dependencies:

I had the same problem and solved it this way with a template default
argument.

// TEST
template <class T, class T1 = Bar<T> >
class Foo
{
  public:
     Foo(){TRACE("\nFoo construct");}
     friend T1;
  private:
     void TestFoo(){TRACE("\nTest private Foo");};
};

template <class T>
class Bar
{
  public:
    Bar(Foo<T> & foo):m_foo(foo){TRACE("\nBar construct");}
    void TestBar(){m_foo.TestFoo();};
  private:
    Foo<T> & m_foo;
};

void test()
{
    Foo<int> fi;
    Bar<int> bi(fi);
    bi.TestBar();
}

// TEST END


BM> I have code in my program that has some circular template class
BM> dependencies:
BM>
BM> template <class T>
BM> class Foo
BM> {
BM>     friend class Bar<T>;
BM>     ...
BM> };
BM>
BM> template <class T>
BM> class Bar
BM> {
BM> public:
BM>     Bar (Foo<T> & foo);
BM>     ...
BM> };
BM>
BM> I thought this code was correct and it indeed compiled under VC++
BM> 4.0. Recently I bought VC++ 5.0 and this code no longer compiles.
BM> The documentation is explicit about it (see below).
BM> Unfortunately, their advice will not work in my case--if I invert
BM> the definitions, the compiler will barf at the use of Foo<T> in
BM> the constructor of Bar. My question is, is it truly an error in
BM> C++, or is it a quirk in Microsoft's understanding of the
BM> standard.
BM>
BM> Bartosz
BM>
BM> ------------ VC++ documentation------
BM> A class identifier is considered to be a normal class unless
BM> declared to be a class template. For example, the following code
BM> generates an error with Visual C++ 5.0 but not with Visual C++
BM> 4.0:
BM>
BM> template<class T> class X {
BM> friend class Y<T>; //Parsed as Y 'less-than'
BM> //T 'greater-than';
BM> Z<T> mf( ); //Parsed as Z 'less-than' T
BM> //'greater-than';
BM> };
BM>
BM> template<class T> class Y {...};
BM> template<class T> class Z {...};
BM>
BM> X<int> x;
BM>
BM> To fix the problem, forward declare Y and Z before the definition
BM> of X.
BM>
BM> template<class T> class Y {...};
BM> template<class T> class Z {...};
BM>
BM> template<class T> class X {...};
BM> ---
BM> [ comp.std.c++ is moderated.  To submit articles: Try just
BM> posting with your                  newsreader.  If that fails,
BM> use mailto:std-c++@ncar.ucar.edu   comp.std.c++ FAQ:
BM> http://reality.sgi.com/austern/std-c++/faq.html   Moderation
BM> policy: http://reality.sgi.com/austern/std-c++/policy.html
BM> Comments? mailto:std-c++-request@ncar.ucar.edu  ]
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1997/05/04
Raw View
On 03 May 1997 18:14:03 PDT, you wrote:

: I have code in my program that has some circular template class
: dependencies:

: template <class T>
: class Foo
: {
:     friend class Bar<T>;
:     ...
: };

: template <class T>
: class Bar
: {
: public:
:     Bar (Foo<T> & foo);
:     ...
: };

: I thought this code was correct and it indeed compiled under VC++ 4.0.
: Recently I bought VC++ 5.0 and this code no longer compiles.

There is another thread on the same subject with statements about
conforming to the draft.  Let me go back to the problem as it was in
the original cfront.  I think the solution for that may be a
workaround with your current VC++.

Template <class T> class Bar;
Template <class T> class Foo {
 friend Bar<T>;
. ...

This does not solve all problems, but it does take care of the simple
cases like yours.

Good luck,
John
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: "Bartosz Milewski" <bartoszm@halcyon.com>
Date: 1997/05/03
Raw View
I have code in my program that has some circular template class
dependencies:

template <class T>
class Foo
{
    friend class Bar<T>;
    ...
};

template <class T>
class Bar
{
public:
    Bar (Foo<T> & foo);
    ...
};

I thought this code was correct and it indeed compiled under VC++ 4.0.
Recently I bought VC++ 5.0 and this code no longer compiles.
The documentation is explicit about it (see below). Unfortunately, their
advice will not work in my case--if I invert the definitions, the compiler
will barf at the use of Foo<T> in the constructor of Bar. My question is,
is it truly an error in C++, or is it a quirk in Microsoft's understanding
of the standard.

Bartosz

------------ VC++ documentation------
A class identifier is considered to be a normal class unless declared to be
a class template. For example, the following code generates an error with
Visual C++ 5.0 but not with Visual C++ 4.0:

template<class T> class X {
friend class Y<T>; //Parsed as Y 'less-than'
//T 'greater-than';
Z<T> mf( ); //Parsed as Z 'less-than' T
//'greater-than';
};

template<class T> class Y {...};
template<class T> class Z {...};

X<int> x;

To fix the problem, forward declare Y and Z before the definition of X.

template<class T> class Y {...};
template<class T> class Z {...};

template<class T> class X {...};
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]