How to forward declare a class in namespace?

Discussion in 'C++' started by yuliy@gmx.de, Nov 29, 2005.

  1. Guest

    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
    , Nov 29, 2005
    #1
    1. Advertising

  2. Dervish Guest

    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.
    Dervish, Nov 29, 2005
    #2
    1. Advertising

  3. Gabriel Guest

    wrote:
    > 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
    Gabriel, Nov 29, 2005
    #3
  4. Gabriel Guest

    Dervish wrote:
    > 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?
    Gabriel, Nov 29, 2005
    #4
  5. Neil Cerutti Guest

    On 2005-11-29, Gabriel <abuse@127.0.0.1> wrote:
    > // 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.

    --
    Neil Cerutti
    Neil Cerutti, Nov 29, 2005
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. amit gulati

    forward declare a template class

    amit gulati, Nov 17, 2003, in forum: C++
    Replies:
    1
    Views:
    461
    Victor Bazarov
    Nov 17, 2003
  2. Binary

    typedef forward declare

    Binary, Dec 5, 2006, in forum: C Programming
    Replies:
    20
    Views:
    861
    santosh
    Jan 27, 2007
  3. Divick
    Replies:
    9
    Views:
    599
    Divick
    Nov 8, 2005
  4. Replies:
    23
    Views:
    2,669
    Shezan Baig
    Jan 31, 2006
  5. Daniel T.
    Replies:
    1
    Views:
    322
    Kai-Uwe Bux
    Jan 20, 2009
Loading...

Share This Page