C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

How to forward declare a class in namespace?

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
yuliy@gmx.de
Guest





PostPosted: Tue Nov 29, 2005 8:50 am    Post subject: How to forward declare a class in namespace? Reply with quote



Hello gurus,

I stuck in following: how can I do forward declaration if the forward
declared class is in some namespace?

something like

// header

class std::string; // approach#1

namespace std
{
class string; // approach#2
};

struct A
{
A();
~A();
std::string * p;
};

both approaches does not compiled.
So, How can I do it?

Thanks

Back to top
Dervish
Guest





PostPosted: Tue Nov 29, 2005 9:11 am    Post subject: Re: How to forward declare a class in namespace? Reply with quote



Following compiles well:
namespace std_
{
class string; // approach#2
};

struct A
{
std_::string * p;
};

So the problem is not in forward decalration in namespace. Actually
std::string is not a class but a typedef to template basic_string
instantiated with type char. Therefore forward declaration fails. So I
think there is no legal way to forward declare std::string.
Only classes accessed through <iostream> can be forward declared in
STL. One can use <iosfwd> to do this.

Back to top
Gabriel
Guest





PostPosted: Tue Nov 29, 2005 9:24 am    Post subject: Re: How to forward declare a class in namespace? Reply with quote



[email]yuliy (AT) gmx (DOT) de[/email] wrote:
Quote:
Hello gurus,

I stuck in following: how can I do forward declaration if the forward
declared class is in some namespace?

something like

// header

class std::string; // approach#1

namespace std
{
class string; // approach#2
};

struct A
{
A();
~A();
std::string * p;
};

both approaches does not compiled.
So, How can I do it?

Thanks


Approach #2 works in general. See this example, which compiles just fine
(compiling using cygwin: cygming special):

namespace ns
{ struct A; }

struct B
{ ns::A* a; };

namespace ns
{ struct A {}; }

int main()
{
B b; // "unused variable", I know
return 0;
}

You problem is that you got the type of std::string wrong. So, you
create a conflict between you saying
namespace std { class string; }
and the <string> header saying something else.
Consider this example, which also works:

// header.hpp
namespace std
{
template<typename _CharT, typename _Traits, typename _Alloc> class
basic_string;
typedef basic_string<char> string;
}
struct B
{ std::string* s; };

// main.cpp
#include <string>
#include "header.hpp"

int main()
{
B b;
return 0;
}

In the forward declaration I use the declaration which is also used in
the <string> library header.

Sadly, the above is still implementation-dependent. I would appreciate
some enlightenment how to do this really non-implementation-dependent.

Gabriel

Back to top
Gabriel
Guest





PostPosted: Tue Nov 29, 2005 9:26 am    Post subject: Re: How to forward declare a class in namespace? Reply with quote

Dervish wrote:
Quote:
Following compiles well:
namespace std_
{
class string; // approach#2
};

struct A
{
std_::string * p;
};

So the problem is not in forward decalration in namespace. Actually
std::string is not a class but a typedef to template basic_string
instantiated with type char. Therefore forward declaration fails. So I
think there is no legal way to forward declare std::string.
Only classes accessed through <iostream> can be forward declared in
STL. One can use <iosfwd> to do this.

Why is that?

Back to top
Neil Cerutti
Guest





PostPosted: Tue Nov 29, 2005 12:31 pm    Post subject: Re: How to forward declare a class in namespace? Reply with quote

On 2005-11-29, Gabriel <abuse (AT) 127 (DOT) 0.0.1> wrote:
Quote:
// header.hpp
namespace std
{
template<typename _CharT, typename _Traits, typename _Alloc> class
basic_string;
typedef basic_string<char> string;
}
struct B
{ std::string* s; };

// main.cpp
#include <string
#include "header.hpp"

int main()
{
B b;
return 0;
}

In the forward declaration I use the declaration which is also
used in the
Sadly, the above is still implementation-dependent. I would
appreciate some enlightenment how to do this really
non-implementation-dependent.

It can't be done. The implementation is allowed to include extra
trailing template parameters in the basic_string template, so no
forward declaration of std::basic_string will be portable.

A proxy class that contains a std::string could be used instead.

class string_proxy;

struct b
{
string_proxy *s;
};

string_proxy could be defined in your .cpp file.

#include <string>

class string_proxy
{
std::string s_;
public:
string_proxy(const std::string& s): s_(s) { }
std::string& operator() { return s_; }
const std::string& operator() const { return s_; }
};

The above is a simple-minded example; you might want something
with an automatic conversion to std::string, or implement the
subset of the std::string interface that you need for class B.

--
Neil Cerutti

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.