1

I need a template class that maps a family non-overloaded, non-template c-function into C++ template function in order to make subsequent code more generic:

For example suppose, a C-library has these function for a bunch of types:

c_fun_float(...)
c_gun_float(..)

c_fun_double(...)
c_gun_double(..)

That I want to generally call as

cpp<T>::fun(...)
cpp<T>::gun(..)

in C++11.

For that, I am using this pattern:

template<class T> cpp;

template<> cpp<double>{
    "static fun maps to c_fun_double"; // pseudo code
    "static gun maps to c_gun_double"; // pseudo code
};
template<> cpp<float>{
    "static fun maps to c_fun_float"; // pseudo code
    "static gun maps to c_gun_float"; // pseudo code
};

The question is how write this mapping code. The first attempt was (maybe abusing of C++11):

template<> cpp<double>{
    static constexpr auto fun = &c_fun_double; // nice short code!
    static constexpr auto gun = &c_gun_double;
};
... corresponding code for float ...

Which look pretty clean. However I later realized that these are pointers to functions not "real" functions (for example cannot be inlined?). On the other hand they are constexpr so maybe in effect it the can direct call (unlikely).

So I decided to change the code to

template<> cpp<double>{
    template<class... Args>
    static inline auto fun(Args&&... args) -> decltype(c_fun_double(std::forward<Args>(args)...)){
       return c_fun_double(std::forward<Args>(args)...);
    } // lots of typing!
    template<class... Args>
    static inline auto gun(Args&&... args) -> decltype(c_gun_double(std::forward<Args>(args)...)){
       return c_gun_double(std::forward<Args>(args)...);
    }
    // perhaps write a macro
};
... corresponding code for float ...

The question is, what is better? to have

  1. a static constexpr function pointer (less verbose, may(?) have indirect call penalty) or
  2. a static inline perfect forward function (more verbose, but direct call, works with overloads if necessary).

Is there an advantage in one approach over the other?

Maybe another way to put the question, do constexpr pointers to function produce indirect calls via a runtime pointer?

alfC
  • 14,261
  • 4
  • 67
  • 118
  • 5
    both sound like a micro optimization – BЈовић Dec 01 '14 at 07:15
  • 2
    If you care about the speed here, I would simply measure it. What I would be most concerned about would be readability. – daramarak Dec 01 '14 at 07:17
  • Why do you bother perfectly forwarding something to a C function? – T.C. Dec 01 '14 at 09:02
  • @T.C., sure, it is just that `static inline auto gun(Args&&... args){return c_gun_double(args...);}` sounded wrong. – alfC Dec 01 '14 at 14:38
  • @BЈовић, what do you mean by "both"? I really need the function call to be (template) generic from the C++ perspective. – alfC Dec 15 '14 at 22:21
  • 1
    First of all, I do not see what exactly is the problem, and this sounds like x-y question. To answer your last question : yes, it is still an indirect call (compile to assembly code and see what exactly is produced). – BЈовић Dec 16 '14 at 07:17
  • Ok, thanks @BЈовић, I think that answers the question. So the forward call is direct but the pointer is indirect even if it is `constexpr` (Sorry my ignorance, I don't know how to analyze the assembly code.) Besides I though that it could be up to the compiler to treat `constexpr` function pointers as direct calls. – alfC Dec 16 '14 at 20:35
  • @BЈовић, I also see your point, the question is confusing because it has the template aspect to it, maybe to illustrate a case but not fundamental. It could have been clear in the context of this question: http://stackoverflow.com/questions/13698989/what-is-the-best-way-of-renaming-alias-forward-a-function-in-c – alfC Dec 16 '14 at 20:40

0 Answers0