Re: forward declarations and namespaces?

From: Steven T. Hatton (susudata_at_setidava.kushan.aa)
Date: 04/30/04


Date: Thu, 29 Apr 2004 19:50:31 -0400

Dave Moore wrote:

> As with std::ostream, std::valarray is not a simple class type,
> therefore, an attempt to forward declare it like:
>
> using namespace std;
> class valarray;

I didn't even want to introduce the namespace at that point. I find
the /using/ directive for namespaces to be contrary to my sense of order.
I much prefer introducing specific names as needed with /using/
declaration.
 
> will fail. Unfortunately there is AFAIK no mechanism like <iosfwd>
> providing forward declarations of other STL classes. OTOH, you can
> probably roll your own by looking at the examples in <iosfwd> ...
> without checking myself, I expect something like:

I used something that I'm pretty sure is either explicitly undefined, or
non-conforming by introducing my own names into std:: This is the whole
ugly solution I cam up with:

/*************
  Makefile
/*************
forward : forward.hpp forward.cc main.cc
        g++ -o forward forward.cc main.cc
clean:
        rm *.o forward

/*************
  forward.cc
/*************

#include "forward.hpp"
#include <iostream>
#include <valarray>

V::V(const size_t& size){
  va = new std::valarray<double>(1.1,size);
}

std::ostream& V::stringify(std::ostream& out){
  for(size_t i = 0; i < va->size(); i++)
    {
      out << (*va)[i] << " ";
    }
  return out;
}

/*************
  forward.hpp
/*************

#ifndef FORWARD_HPP
#define FORWARD_HPP

#include <iosfwd>
#include "stringable.hpp"

namespace std{
  template<class> class valarray;
}

struct V: public Stringable {
  V(const size_t& size);
  std::valarray<double>* va;
  std::ostream& stringify(std::ostream& out);
};

#endif

/*************
  main.cc
/*************

#include "forward.hpp"
#include <iostream>

int main(int argc, char* argv[]) {
  V v(10);
  std::cout << v << "\n";
}

/*************
  stringable.hpp
/*************

#ifndef STRINGABLE_H
#define STRINGABLE_H
#include <iosfwd>

using std::ostream;
  
/**
   An un-universal base class
*/
class Stringable {
public:
  virtual ostream& stringify(ostream& out)=0;
};
  
inline ostream& operator<<(ostream& out, Stringable& s){
  s.stringify(out);
  return out;
}

#endif

> using namespace std;
> template <class T> class valarray;
>
> should remove the need to include <valarray> in your header file.

That is, if I have std:: available from some other #include. As You see
from the code above, I actually opened the std namespace up, and put my own
forwar declaration in there.

I have to wonder how many problems exist with the 'solution' I presented
above.

-- 
STH 
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org  SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org


Relevant Pages

  • Re: friend operator << overload ambiguity error
    ... > namespace std { ... we users are not allowed to "pollute" the std ... with your declaration of operator<< for Thing, ...
    (comp.lang.cpp)
  • Re: everywhere, i need to use std::
    ... But what I was referring to was not the use of "using namespace" but the ... >> if you wanted to use identifiers from std overridden by ones in stdcli ... Having to insert a using declaration, or use the namespace:: prefix, ... the only namespaces I would use with using directives ...
    (comp.lang.cpp)
  • Re: Visual .NET 2003 local struct definition bug
    ... kind of error because the structures are not declared in the header files. ... So, if I understand, I must always use an anonymous namespace everywhere I ... GUID g; ... To fix the declaration errors, ...
    (microsoft.public.dotnet.languages.vc)
  • Re: friend operator << overload ambiguity error
    ... > standard. ... > users to add names to namespace std under the right circumstances. ... A program may add template specializations for any standard library template ...
    (comp.lang.cpp)
  • Re: everywhere, i need to use std::
    ... >> It's normally safe to include namespace std in a module, ... >> don't also globally include another namespace as well. ... An extern library/framework providing ... stdcli:: as needed, to make it obvious which one is being used. ...
    (comp.lang.cpp)