6

I'm trying to write a library where I have some templated functions, some of which are helper functions so I don't want my users to have access to them. Some basic code might be

//mylib.h

namespace myfuncs
{
    template<class T>
    void helper (T input, int extrainformation)
    {
       //do some usefull things
    }

    template<class T>
    void dostuff(T input)
    {
       int someinfo=4;
       helper(input, someinfo);
    }
}

Is it possible to somehow hide the helper function so that users of the library can't call it directly? I had thought an unnamed namespace might do the job but because I'm using templates I can't split the function declaration and body between a header and implementation file. Putting the unnamed namespace in a header file is of no use and bad style. The only thing I can think to do is create a mylib class and encapsulate the functions as private/public static functions.

Any better solutions would be much appreciated.

Phil

Luc Touraille
  • 79,925
  • 15
  • 92
  • 137
Phil Rosenberg
  • 1,597
  • 1
  • 14
  • 22
  • 1
    I suggest change `namespace` to `class` and make all functions `static`, and then put your `helper` in `private`. – neuront Nov 17 '11 at 13:15

3 Answers3

8

One way to do it is to have a "detail" or "internal" namespace. Thats how many libraries do it.

namespace myfuncs
{
    namespace detail
    {
        template<class T>
        void helper (T input, int extrainformation)
        {
           //do some usefull things
        }
    }

    template<class T>
    void dostuff(T input)
    {
       int someinfo=4;
       detail::helper(input, someinfo);
    }
}
ronag
  • 49,529
  • 25
  • 126
  • 221
4

Do what many template libraries (like Eigen) do: use a clearly named implementation-specific namespace (such as myfuncs::impl) and rely on social encapsulation (i.e. the user not willing to call templates from the implementation namespace).

Luc Touraille
  • 79,925
  • 15
  • 92
  • 137
thiton
  • 35,651
  • 4
  • 70
  • 100
  • 1
    And documentation: we guarantee a stable interface, except for what is in `impl`, and if you chose to rely on it we don't care if your software breaks on upgrade. – Matthieu M. Nov 17 '11 at 16:40
0

You can:
In header.h:

#ifndef AAA_H
#define AAA_H
namespace myfuncs
{
    template<class T>
    std::string dostuff();
}
#include "aaa.cpp"
#endif // AAA_H

In source.cpp:

#define AAA_CPP
#include <string>
namespace {
  template<class T>
  std::string helper ()
  {
     return "asdf";
  }
}

namespace myfuncs
{
    template<class T>
    std::string dostuff()
    {
        return helper<T>();
    }
}
#endif // AAA_CPP

In main.cpp:

#include <iostream>
#include "aaa.h"

int main(int argc, char *argv[])
{
  std::cout << myfuncs::dostuff<std::string>();
  return 0;
}
aviit
  • 1,957
  • 1
  • 27
  • 50