Question

This pseudo-code was obtained from GotW #53 under the subtitle "A Not-So-Good Long-Term Solution". I've been trying to understand for a few hours already what the author is saying, specially in relation to the comment starting with "// error: potential ..." below, to no avail. I would really appreciate some help on this.

    //  Example 2c: Bad long-term solution (or, Why to
    //              avoid using declarations in
    //              headers, even not at file scope)
    //
    //--- file x.h ---
    //
    #include "y.h"  // declares MyProject::Y and adds
                    //  using declarations/directives
                    //  in namespace MyProject
    #include <deque>
    #include <iosfwd>
    namespace MyProject
    {
      using std::deque;
      using std::ostream;
      // or, "using namespace std;"
      ostream& operator<<( ostream&, const Y& );
      int f( const deque<int>& );
    }
    //--- file x.cpp ---
    //
    #include "x.h"
    #include "z.h"  // declares MyProject::Z and adds
                    //  using declarations/directives
                    //  in namespace MyProject
      // error: potential future name ambiguities in
      //        z.h's declarations, depending on what
      //        using declarations exist in headers
      //        that happen to be #included before z.h
      //        in any given module (in this case,
      //        x.h or y.h may cause potential changes
      //        in meaning)
    #include <ostream>
    namespace MyProject
    {
      ostream& operator<<( ostream& o, const Y& y )
      {
        // ... uses Z in the implementation ...
        return o;
      }
      int f( const deque<int>& d )
      {
        // ...
      }
    }

No correct solution

OTHER TIPS

His is saying to not use the using directive in a header file. For example: Suppose that we had 2 files x.h and z.h with those declarations:

// x.h
namespace MyProject
{
  using std::deque;
  using std::ostream;
  ....
};

// z.h
namespace MyProject
{
  using mystd::deque;
  using mystd::ostream;
  ....
};

The question is: which ostream object will be called in your example?

// x.cpp
#include "x.h"
#include "z.h"
#include <ostream>
namespace MyProject
{
  ostream& operator<<( ostream& o, const Y& y )
  {
    // ... uses Z in the implementation ...
    return o;
  }
  int f( const deque<int>& d )
  {
    // ...
  }
}

You would like to call x.h definitions, but due the order of includes, it will call the z.h includes definitions

The author is saying that the problem with this code is that as this code is used in other applications, there may be multiple things with the same name ("potential future namespace ambiguities"), depending on what namespaces are used in other header files. If they say that a different namespace should be used, the same name may not point to what the author originally intended.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top