How to forward declare a class in namespace?

Y

yuliy

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
 
D

Dervish

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.
 
G

Gabriel

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
 
G

Gabriel

Dervish said:
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?
 
N

Neil Cerutti

// 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.

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top