 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
yuliy@gmx.de Guest
|
Posted: Tue Nov 29, 2005 8:50 am Post subject: How to forward declare a class in namespace? |
|
|
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
|
Posted: Tue Nov 29, 2005 9:11 am Post subject: Re: How to forward declare a class in namespace? |
|
|
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
|
Posted: Tue Nov 29, 2005 9:24 am Post subject: Re: How to forward declare a class in namespace? |
|
|
[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
|
Posted: Tue Nov 29, 2005 9:26 am Post subject: Re: How to forward declare a class in namespace? |
|
|
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
|
Posted: Tue Nov 29, 2005 12:31 pm Post subject: Re: How to forward declare a class in namespace? |
|
|
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 |
|
 |
|
|
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
|
|