14

In C++ an anonymous namespace is equivalent to:

namespace $$$$ {
  //something
}
using namespace $$$$;

Where $$$$ is some kind of unique identifier. Anonymous namespace are then useful for code that should not be seen outside the compilation unit.

So far so good, however recently I started to write some code with templates, such code must be in headers so using anonymous namespaces does not make much sense as the mere inclusion of the header will nullify the isolation effect.

Then the question is, what is the suggested way in this cases? I started using a named namespace called Private. It does not really stop anyone who wants to use the identifiers inside, but at least it reduces the name clashes to id "Private."

Are there better ways? Suggestions?

JBL
  • 12,588
  • 4
  • 53
  • 84
Paolo.Bolzoni
  • 2,416
  • 1
  • 18
  • 29
  • 5
    AFAIK that's all you can do, template libraries often use namespaces such as `detail` for this very purpose. – user657267 Sep 30 '14 at 10:12
  • Ideally all your code should be in some kind of namespace. Put your templates into some kind of namespace called Utility, or Alpha or MyWork or something. And put the help functions in there too. – Neil Kirk Sep 30 '14 at 10:18
  • Thanks user657267; that was the confirmation I was looking for. I was afraid I was missing the obvious. – Paolo.Bolzoni Sep 30 '14 at 12:19

3 Answers3

5

If you're desperate for that isolation, why not the good old file-static? It was undeprecated:

template <typename T>
static void foo()
{}

int main()
{
    foo<char>();
}

Then again, if you only need foo within one translation unit, then presumably you're only including it in a header within that translation unit, and then it doesn't matter whatsoever whether it's "in a header". So, simply do not include the templates in other translation units and you've already largely achieved your goal of isolation.

To really guarantee isolation for all possible instantiations (i.e. including those that you've created within this TU), use static as above or simply document your intent using a detail namespace.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
5

Stick with your Private namespace (or use the more popular detail). Remember the main idea behind C++ access mechanisms is make it difficult to misuse them, not impossible. Protect yourself against accidents, not malicious attacks.

Paul Evans
  • 27,315
  • 3
  • 37
  • 54
1

The most usual way to hide implementation of template code within a header is to put the implementation into a namespace called detail.

For example:

namespace cpputil { // my c++ utility library namespace

  namespace detail { // implementation details of this libraries headers go here

    // a functor private to the library
    template<class T>
    struct private_functor {
      private_functor(const T& t) : _t(t) {}
      void write(std::ostream& os) const { _t.write(os); }
    private:
      const T& _t;
    };

    // an extension to std::ostream::operator<<
    template<class T>
    std::ostream& operator<<(std::ostream& os, const private_functor<T>& pf)
    {
      pf.write(os);
      return os;
    }
  }

  /// a public template function that is designed to allow an object to be emitted to a stream
  /// returns a function object that calls T::write(std::ostream&) when placed into an
  /// output stream
  template<class T>
  detail::private_functor emit(const T& t) {
    return detail::private_functor<T>(t);
  }
}

// can be used like this:

int main() {
  struct S {
    void write(std::ostream& os) const { os << "{I am an S}"; }
  };

  std::cout << cpputil::emit(S) << std::endl;
  return 0;
}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142