Skip to main content
GameDev.net gamedev.net
🔒 Locked

Hiding function template declaration (C++)

Started by Mr Awesome Mar 28, 2007 at 10:09 PM 5 replies 3.5k views
Original Post
Mr Awesome
Mr Awesome
In a header file, I have declared a few function templates that aid the primary function templates in the header. I would like to prevent other files from using these utility functions, as they do not belong in the public interface. Because function templates must be defined in a header, however, I am finding this difficult. Neither the static keyword nor anonymous namespaces seem to hide the function templates from use by other files. Is there any way to do this?
Zahlman
Zahlman
If you only need the template to work with a known set of types, you could put the definitions into the source file and instantiate the template explicitly for each type.

Otherwise, I think you're SOL. But you can at least hide the template definitions in a separate file, which is #included from the header (it is common to use another filename extension for such files, such as .inl).
Zakwayda
Zakwayda
Just as an additional note, it's fairly common to place implementation details in a nested namespace, commonly named detail.

This of course doesn't hide said implementation details per se, but it does strongly suggest to the user that they're not part of the public interface.

If you take a look at boost::shared_ptr, for example, you'll see that various implementation details live in the boost::detail namespace, and are readily accessible. For example, once you've included boost/shared_ptr.hpp, you can freely create objects of type shared_count, or call functions such as sp_enable_shared_from_this(), even though these are clearly not part of the public interface.
Antheus
Antheus
Use classes, it's what they're there for.

struct Utility{  template <typename T>  static void foo( T x )  {    x += bar_helper(x)    x += another_bar_helper(x);    x += and_another_bar_helper(x);  }private:  template <typename T>  static T bar_helper( T param );   template <typename T>  static T another_bar_helper( T param );  template <typename T>  static T and_another_bar_helper( T param );};......Utility::foo(17);


jpetrie
jpetrie
Quote:

Use classes, it's what they're there for.

That is decidedly not what classes are for, and that approach to the problem will probably not scale well for the OPs needs.

Quote:

Because function templates must be defined in a header, however, I am finding this difficult.

The definition of the template needs to be available any place the template would be used. This typically means you must put the definition in the header, because typically you're writing something that will be part of the public interface of your API or whatnot.

However, if you intend your templates to be used only internally, you can place them in a header that is itself only included by the source files, and never by any public header files, which means the header containing the template definitions doesn't need to be shipped with your library. Alternatively,, if they only are used within one source file, just put them in that source file. Alternatively, simply place them in a namespace to discourage use.
Antheus
Antheus
Quote:
Original post by jpetrie
Quote:


Use classes, it's what they're there for.

That is decidedly not what classes are for, and that approach to the problem will probably not scale well for the OPs needs.


Classes are a way of hiding both, implementation and data.

Granted, they offer more, but by definition, classes encapsulate functionality, hiding it from users. So I would assume it's a perfectly valid solution.

Or perhaps I misunderstood the original question.

Templates and implementations of functions using templates must of course be available to caller, but that is a natural consequence of using them in the first place. The utility functions however, need not.

Quote:
prevent other files from using these utility functions, as they do not belong in the public interface.


... which is exactly what using classes allows you to do, without abusing language in any way. In our case, they happen to only contain static members, and act merely as extension to namespaces, allowing private members.
Kylotan
Kylotan
I would suggest that time spent trying to hide one part of your code from another part of your code, when you know full well not to call those functions, and that it's easy to wrap them in a 'private' namespace or the like, means you're just wasting your time on something well-meaning but completely pointless.

Alternatively, reconsider the location of these templates. If they're not used by every file that includes that header, then they don't need to be in that header. It's not that "function templates must be defined in a header", it's that they need to be visible at compile time to every file that requires them. I often put private template functions directly into the lone .cpp files where they are used.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.