Question: How to build a good template-based C++ library?

Question

How to build a good template-based C++ library?

Answers 1
Added at 2016-12-07 20:12
Tags
Question

I'm designing a high-performance c++ math library that (ideally) should work with any field (in a math context, so real or complex numbers) and vector space. I initially thought that using templates would do the trick, but I kept finding myself debugging linker and compiler errors more than actually writing useful code.

An example of the code I'm trying to build is the following:

 template<class F, class G>
    class LinearOperator { // For example a matrix multiplication A*x
        Vector<G> Apply(const Vector<F>& vec);   // Compute y = A*x
        Vector<F> Adjoint(const Vector<G>& vec); // Compute x = transpose(A)*y
    }

So that one could inherit from LinearOperator to build their own and have the freedom to chose the input and output vector spaces. For example in the case of an implementation of the Fourier Transform for real numbers, the input vector would have real (say double) entries, but the output vectors should be of a complex type.

From what I've researched, there are basically two options

  • Implement all the functions in the header so the linker would always inline them when called.

    Pros: No linker errors when just including the headers.

    Cons: This would probably increase the binary size and could make the code run slower (?).

  • Explicitly declare types in some cpp implementation file (as template class LinearOperator<double, std::complex<double>>). But I would like to leave the decision to the users.

    Pros: Implementation separated from declaration. Better binary sizes and (maybe?) compile-time optimisations.

    Cons: Only a limited number of types could be used, so the library would be less flexible. Also, declaring explicit types looks kinda weird.

I have worked with c++ in the past but never really designing a library nor have I extensively used templates. Do you have any insights on how this could be done? Or any comment on the options I described? For example, I am not completely sure if the first option is less performant than the second one.

Answers to

How to build a good template-based C++ library?

nr: #1 dodano: 2016-12-07 21:12

I wouldn't implement them in the header. That can cause headaches for people depending on how they are using the libraries.

You can implement all the functionality in source files without actually specifying real template params:

template<typename F, typename G>
Vector<G> LinearOperator<F,G>::Apply(const Vector<F>& vec) {
 //implement using F and G
}

This isn't really going to affect the size of your library. The compiler will only make copies of your classes with the template params substituted when it encounters an actual concrete type being used.

You probably don't want to explicitly declare all the possible types in a source file. This will cause longer compilation time and a larger library. You could include a list of all the acceptable concrete types in documentation, or commented out somewhere.

Source Show
◀ Wstecz