How to create a library that wraps an object with a template function using a minimum includes?

advertisements

The goal of this project is to create a library for distribution. In the past, I used forward declares so I didn't have to distribute a bunch of header files along with the libraries. However, I'm now trying to eliminate code duplication by switching to templates and am running into some issues.

First, a simple example project showing what is currently working:

//LibraryDep1.h

class LibraryDep1
{
public:
    LibraryDep1(void) {};
    virtual ~LibraryDep1(void) {};

    template <typename T>
    int TestFunction(T value)
    {
        std::cout << value << std::endl;
        return 0;
    }
};

//LibraryInclude.h

class LibraryDep1; //forward declare

class LibraryInclude
{
private:
    LibraryDep1* mLibDep1;
public:
    LibraryInclude(void);
    virtual ~LibraryInclude(void);

    int TestFunction(int value);
    int TestFunction(std::string value);

};

//LibraryInclude.cpp

#include "LibraryInclude.h"
#include "LibraryDep1.h"

LibraryInclude::LibraryInclude(void)
{
    this->mLibDep1 = new LibraryDep1();
}

LibraryInclude::~LibraryInclude(void)
{
    delete this->mLibDep1;
}

int LibraryInclude::TestFunction(int value)
{
    return this->mLibDep1->TestFunction(value);
}

int LibraryInclude::TestFunction(std::string value)
{
    return this->mLibDep1->TestFunction(value);
}

//main.cpp
#include <tchar.h>
#include "LibraryInclude.h"

int _tmain(int argc, _TCHAR* argv[])
{
    LibraryInclude inclLibrary;
    inclLibrary.TestFunction(77);
    inclLibrary.TestFunction("test");
}

This gives the expected output of:

77
test

However, the overloads of LibraryInclude::TestFunction could be replaced with a template function to further reduce code duplication:

//LibraryInclude.h

class LibraryDep1; //forward declare

class LibraryInclude
{
private:
    LibraryDep1* mLibDep1;
public:
    LibraryInclude(void);
    virtual ~LibraryInclude(void);

    template <typename T>
    int TestFunction(T value) {
      return mLibDep1->TestFunction(value);
    }

};

The problem now is that I'm using mLibDep1 without including the full implementation giving me an undefined type compilation error. Meaning that I need to #include "LibraryDep1.h" in LibraryInclude.h, thus requiring me to distribute both LibraryInclude.h and LibraryDep1.h with my library. This is a simple example, the real project has many header files that would need to be distributed if I were to switch to using the templated version of LibraryInclude.

My question is, is there any way to avoid having to distribute a bunch of include files with my library and eliminate code duplication? Or, am I better off just overloading for all known types (drastically reducing library flexibility) in the distributed header file and keeping the templates in only the underlying classes?


No. There is currently no way to do what you want. When compiler vendors start implementing the 'export' keyword you'll be in luck. Currently I only know of Comeau doing so. This keyword has been around for years so I wouldn't hold my breath until the rest implement it.