1

I have a class template that looks like this:

foo.h

template<class C>
class Foo
{
public:
    void memberFunc();
};
#include "foo.tpp"

foo.tpp

void Foo::memberFunc()
{
    ...
}

Ignore the .tpp file, it's just something I do to give the illusion of separating declaration and implementation, obviously that's (kind of) not possible with templates.

My implementation file is much longer in reality, and inside it I have some global scope helper function templates that the member functions use, functions that don't make sense as member functions and that I don't want users of the class to have anything to do with.


template<class C> int helper1() { ... }

template <class C> void helper2() { ... }

template<class C>
void Foo<C>::memberFunc()
{
    ...
    helper1<float>();
    ...
    helper2<C>();
    ...
}

I do this all the time in .cpp-implementation files and I forgot that when I do it in this fake version of a .cpp file, the declaration and implementation of these little helper functions actually end up in the class template header file. This leads to users of the class template header getting their namespaces cluttered with helper functions that are useless outside the member function implementations.

Obviously I could just put them in a namespace:

namespace foo_helpers
{

template<class C> void helper1() {...}

template<class C> int helper2()  {...}

}

But it still leads to outside code being able to use these functions. They only matter to the implementation of the member functions and I want that to be reflected.

When looking for a solution, I learned about the concept of unnamed namespaces. As I understand it, they only allow the current translation unit access to its contents. That sounds like exactly what I need, so I changed the helper functions to this:

namespace
{

template<class C> void helper1() {...}
template<class C> void helper2() {...}

}

But it doesn't work, the functions are still usable from files that include the header.

Is there any way to hide these helper functions from outside code?

JensB
  • 839
  • 4
  • 19
  • 3
    No, namespace foo_helpers is the best you can do unless you are using c++20 modules. – Eugene Nov 27 '21 at 23:27
  • 1
    _"functions that don't make sense as member functions"_ can you describe _why_ you feel they don't make sense? The problem you describe (restricting access to a function) certainly sounds like the problem `private` (and perhaps `static`) member functions solve. – Drew Dormann Nov 27 '21 at 23:31
  • 1
    FWIW, one common convention is to make a `details_` namespace for helper functions like this. It is understood that anything in there can't be relied on and you use it at your own risk. – NathanOliver Nov 27 '21 at 23:31
  • 2
    Make the templated functions `private` members of a class. Then they can't be called, except by members or `friend`s of that class. Catch is, they are seen by the compiler, so there is nothing preventing code from attempting to use the functions - just that the usage will be prevented. Rather than trying to prevent code which can see the functions from using them, place the functions in a source file that ONLY contains other functions that need those templates - so other code cannot even see declaration of those templated functions. – Peter Nov 27 '21 at 23:52

0 Answers0