Anteru's blog
  • Consulting
  • Research
    • Assisted environment probe placement
    • Assisted texture assignment
    • Edge-Friend: Fast and Deterministic Catmull-Clark Subdivision Surfaces
    • Error Metrics for Smart Image Refinement
    • High-Quality Shadows for Streaming Terrain Rendering
    • Hybrid Sample-based Surface Rendering
    • Interactive rendering of Giga-Particle Fluid Simulations
    • Quantitative Analysis of Voxel Raytracing Acceleration Structures
    • Real-time Hybrid Hair Rendering
    • Real-Time Procedural Generation with GPU Work Graphs
    • Scalable rendering for very large meshes
    • Spatiotemporal Variance-Guided Filtering for Motion Blur
    • Subpixel Reconstruction Antialiasing
    • Tiled light trees
    • Towards Practical Meshlet Compression
  • About
  • Archive

C++ tricks, #6: Explicit template instantiation

November 19, 2008
  • Programming
approximately 7 minutes to read

Today we take a look at explicit template instantiations (yet another post which is a direct result of user feedback :) ). With explicit template instantiations, you can define a template and instantiate it in a DLL, so clients don’t even have to see the implementation of the template. All you need is a language extension (extern template) which will become part of C++0x, and is currently supported by GCC, Intel and MSVC.

The DLL

Let’s assume we have this great class:

template <typename T>
class Container
{
public:
    Container (int size);

    ~Container ();

    T Get (int index) const;

    void Set (int index, T value);

private:
    T* data_;
};

and we want to provide our clients an instance which works with integers only. For this to work, we put the definition into a separate file (you’ll see later why), container_impl.h:

template <typename T>
Container<T>::Container (int size)
{
    data_ = new T [size];
}

template <typename T>
Container<T>::~Container ()
{
    delete [] data_;
}

template <typename T>
T Container<T>::Get (int index) const
{
    return data_ [index];
}

template <typename T>
void Container<T>::Set (int index, T value)
{
    data_ [index] = value;
}

Then we include both in a file in our DLL, let’s call it container_in.cpp like this:

#include "container.h"
#include "container_impl.h"

template class __declspec(dllexport) Container<int>;

Now clients can already use the integer container, by including only container.h which does not contain the definitions!

More flexibility

But what if clients want to use a float container? With the current solution, they’ll get an error that the definition is not available. To get it working, the client has to include container_impl.h as well. But now, Container<int> will be instantiated twice, which leads to an error. The workaround is to define the instantiation as extern template, which means don’t generate code for this template even if the definition is available (for some reason or another, I just tried and it also works without the extern with Visual C++ 9). The finished file is:

#ifdef DLL_EXPORT // Set to true when you build the dll
#define API __declspec(dllexport)
#else
#define API __declspec(dllimport)
#endif

template <typename T>
class Container
{
// Container declaration
};

#ifndef IN_ // Note: For VC++, you can leave out the extern
extern template class API Container<int>;
#endif

The container_in.cpp file has to #define IN_ now. The client works like this:

#include "../shared_lib/templ.h"
#include "../shared_lib/templ.hpp"

#include <iostream>

int main (int, char**)
{
    Container<float> c1 (5); // Will be instantiated here

    c1.Set (3, 13.37f);
    std::cout < c1.Get (3) < std::endl;

    Container<int> c2 (4); // Will be linked in from the DLL

    c2.Set (1, 4711);
    std::cout < c2.Get (1) < std::endl;
}

That’s it!

Previous post
Next post

Recent posts

  • Data formats: Why CSV and JSON aren't the best
    Posted on 2024-12-29
  • Replacing cron with systemd-timers
    Posted on 2024-04-21
  • Open Source Maintenance
    Posted on 2024-04-02
  • Angular, Caddy, Gunicorn and Django
    Posted on 2023-10-21
  • Effective meetings
    Posted on 2022-09-12
  • Older posts

Find me on the web

  • GitHub
  • GPU database
  • Projects

Follow me

Anteru NIV_Anteru
Contents © 2005-2025
Anteru
Imprint/Impressum
Privacy policy/Datenschutz
Made with Liara
Last updated February 03, 2019