barej
barej

Reputation: 1406

Convert function template to function overload set

Assuming this is my library. And it is a very huge library:

library.hpp

template<class usertype> void function_name(usertype aaa)
{
}

This is my main

int main()
{
    int x=3;
    function_name(x);
    double y=3.5;
    function_name(y);
    return 0;
}

I do not know what is going inside the library. What I want is to convert the library to adapt my code. In fact, reducing the template into real code.

I need the library code above be converted into:

void function_name(int aaa)
{
}

void function_name(double aaa)
{
}

So I can manipulate the library according to my needs instead of manipulating the general code that works for everybody. How can this conversion from template to real code be done (without manual effort, but in automatic way)?

Edit:

I want to convert the whole file library.hpp into library_2.hpp which contains no template. Instead with two real implemented functions. This is what happens in the middle of the compilation.

I am not looking for reducing the compilation time. I am dealing with a huge library made of 196 files. Among those many functions in the library, I will need a few of them related to my work. I intend to hack and extend this library. Extending the whole library has huge effort cost for me. I just want to extend only what I need. So, it is very important for me to reduce the code and simplify it and remove all templates replacing them with explicit code. I am not good at C++ and it compiler errors. So, in such a huge library, I prefer to use automatic methods rather than involving manual code manipulation. I am also not good at understanding this library. To understand the library, better to convert its complicated functions into explicit implemented code related to what I really need. Then I can understand someones else code better. I will remove the functions not related to my needs. I also do not care about updates coming to the library. Once I establish new library, its maintenance is my duty. And the new library would be much smaller and easier for maintenance. Comments show that some people looking at my aim from different view. I hope this explanation is clear.

In case of curiosity, the library I am going to manipulate is odeint related to mathematical computations with rarely change or bug inside.

Upvotes: 2

Views: 185

Answers (2)

5gon12eder
5gon12eder

Reputation: 25419

I'm not entirely sure what you want to achieve but from reading the comments, I think that your major concern is that you are trying to reduce compile times and get less template-related error messages. You are not trying to specialize library functions for your own types.

If you only instantiate the templated functions from the library with a handful of types, there is a simple recipe to get templates out of your picture. But it will force you to write two lines of code for each combination of templated function and type you want to use it with.

Create your own header file library_wrapper.hpp. There, you declare non-template versions of the functions you want to use.

library_wrapper.hpp

#ifndef LIBRARY_WRAPPER_H
#define LIBRARY_WRAPPER_H

#include <vector>  // just an example

namespace library_wrapper
{
  void
  function_name(int);

  void
  function_name(double);

  int
  another_function(const std::vector<double>&, bool);
}

#endif

And then “implement” them once and for all using your so-little-loved template library.

library_wrapper.cpp

#include "library_wrapper.hpp"
#include <library.hpp>  // the template library

namespace library_wrapper
{
  void
  function_name(const int arg1)
  {
    return library::function_name(arg1);
  }

  void
  function_name(const double arg1)
  {
    return library::function_name(arg1);
  }

  int
  another_function(const std::vector<double>& arg1, const bool arg2)
  {
    return library::function(arg1, arg2);
  }
}

You compile library_wrapper.cpp once, fight the templates, and then continue using only your wrapper which provides the non-templated functions.

Be aware that this approach jeopardizes one of the major reasons templates can be so fast: inlining. Your wrapper functions cannot be inlined at compile-time because you are hiding their definitions from the compiler. This is on purpose and, on the other hand, buys you shorter compile times. Link-time inlining might give you some inlining back but you shouldn't take it as granted.

Note that this solution does not work quite as well with types (as opposed to functions). You could try writing some pimpl-wrappers but I don't recommend this. Maybe the best thing would be to become friends with your template library…

Update addressing your updated question

I am dealing with a huge library made of 196 files. Among those many functions in the library, I will need a few of them related to my work.

In case of curiosity, the library I am going to manipulate is odeint related to mathematical computations with rarely change or bug inside.

This seems like the above approach could indeed help.

Extending the whole library has huge effort cost for me. I just want to extend only what I need. So, it is very important for me to reduce the code and simplify it and remove all templates replacing them with explicit code.

I don't think that this is a good approach. Instead, use the library as a black box and build your own on top of it. Concentrate your developer effort on the new features and benefit from updates for the underlying library.

I assume that the library in question is free software (otherwise, what you want to do would be illegal anyway) and free software project should support each other. If you are building an awesome library Y on top of library X, both projects, X and Y, can benefit. On the other hand, if you rip out only a part of that other library and add other functionality, your two rivalling projects might both end up as something incomplete and incompatible which is frustrating for both, you and your users.

To understand the library, better to convert its complicated functions into explicit implemented code related to what I really need. Then I can understand someones else code better.

I don't think that you can reasonably expect that some machine-generated code will be more readable than the original human-written code of the library. After all, human coders are taught to write code for humans but compilers are optimized for other aspects.

I am not good at C++ and it compiler errors. […] I am also not good at understanding this library.

I intend to hack and extend this library.

I also do not care about updates coming to the library. Once I establish new library, its maintenance is my duty.

I don't want to seem rude but … do you see the problem?

Upvotes: 2

MORTAL
MORTAL

Reputation: 383

by specialization

template<>
void function_name(int aaa)
{
}

template<>
void function_name(double aaa)
{
}

sample code

#include <iostream>
template<class usertype>
void function_name(usertype aaa)
{
    std::cout << "default\n";
}

template<>
void function_name(int aaa)
{
    std::cout << "int value = " << aaa << '\n';
}

template<>
void function_name(double aaa)
{
    std::cout << "double value = " << aaa << '\n';
}

int main()
{
    int x = 3;
    function_name(x);
    double y = 3.5;
    function_name(y);
    struct Z{} z;
    function_name(z);
    return 0;
}

Upvotes: 0

Related Questions