I want to use the pimpl idiom to avoid having users of my library need our external dependencies (like boost, etc) however when my class is templated that seems to be impossible because the methods must be in the header. Is there something I can do instead?
相关问题
- Sorting 3 numbers without branching [closed]
- How to compile C++ code in GDB?
- Why does const allow implicit conversion of refere
- thread_local variables initialization
- What uses more memory in c++? An 2 ints or 2 funct
相关文章
- Class layout in C++: Why are members sometimes ord
- How to mock methods return object with deleted cop
- Which is the best way to multiply a large and spar
- C++ default constructor does not initialize pointe
- Selecting only the first few characters in a strin
- What exactly do pointers store? (C++)
- Converting glm::lookat matrix to quaternion and ba
- What is the correct way to declare and use a FILE
If the class is templated, your users essentially need to compile it (and this is literally true in the most widely-used C++ implementations) and so they need your external dependencies.
The simplest solution is to put the bulk of your class's implementation in a non-template base class (or encapsulated member object of some class). Solve the module-hiding problem there.
And then write the template derived (or enclosing) class to add type safety to it.
For example, suppose you have a template that provides the amazing ability to allocate on first access (omitting the necessary copy constructor, assignment, destructor):
If you wanted the "logic" to be separated into a non-template base class, you'd have to parameterise the behaviour in the non-template way, which is to say, use virtual functions:
Then you can add the type-awareness in the outer layer:
i.e. You use virtual functions to allow the template to "fill in" the type-dependent operations. Obviously this pattern would only really make sense if you have some business logic that is worth the effort of hiding.
You can explicitly instantiate templates in the source file, but that is possible only if you know what the template type is going to be. Otherwise, do not use pimpl idiom for templates.
Something like this :
header.hpp :
source.cpp :
There are two general solutions:
while the interface depends on some type
T
, it defers to a more weakly typed implementation (e.g. one usingvoid*
pointers directly or trough type erasure), oryou support only a specific and quite limited number of types.
The second solution is relevant for e.g.
char
/wchar_t
-dependent stuff.The first solution was quite common in the early days of C++ templates, because at that time compilers were not good at recognizing commonalities in the generated machine code, and would introduce so called “code bloat”. Today, much to the surprise of any novice who tries it out, a templated solution can often have smaller machine code footprint than a solution relying on runtime polymorphism. Of course, YMMV.
Cheers & hth.,