0

I want to build a template helper object using only C++11 that can be used to wrap C functions.

I'm trying to extend the answer given here from a wrapper function to a wrapper object, so that it can contain state:

#include <iostream>
#include <functional>

int foo(int a, int b) { return a + b; }

template<typename Fn, Fn fn, typename... Args>
class AltFuncWrapper
{
public:

    using result_type = typename std::result_of<Fn(Args...)>::type;

    bool enabled{false};

    result_type exec(Args... args)
    {
        if(enabled)
        {
            std::cout << "Run the real thing";
            return fn(std::forward<Args>(args)...);
        }
        else
        {
            std::cout << "Return default value";
            return result_type{};
        }
    }
};

int main()
{
  AltFuncWrapper<decltype(&foo), &foo> wrapper{};
  return 0;
}

But I get the following compiler error(CE link):

<source>: In instantiation of 'class TestDoubleWrapper<int (*)(const char*, unsigned int)throw (), chmod>':
<source>:68:51:   required from here
<source>:30:67: error: no type named 'type' in 'class std::result_of<int (*())(const char*, unsigned int)throw ()>'
     using result_type = typename std::result_of<Fn(Args...)>::type;
                                                                   ^
Bryce Schober
  • 130
  • 10

2 Answers2

1

At no point in the program you specify Args and it can’t be deduced so it turns out to be an empty pack.
You can capture the arguments of the function using a partial specialization:

template<auto F> class C;
template<typename RV, typename ...Args, RV (*F)(Args...)>
class C<F>
{
    ...
Daniel
  • 30,896
  • 18
  • 85
  • 139
  • 1
    Looks to me like this solution requires C++17, where I requested a C++11 possibility. – Bryce Schober Aug 04 '20 at 00:33
  • Thanks @Dani... though your solution doesn't work for C++11, it did prompt me to go back to [the other answer on that question I referred to](https://stackoverflow.com/a/36492736/99518), which led me to my own solution. – Bryce Schober Aug 05 '20 at 03:51
0

@Dani's solution prompted me to go back and look at the other answer on that question I originally referred to, which led me to my own solution:

template<typename FunctionType, FunctionType func> struct AltFuncWrapper;
template<typename ReturnType, typename... Args, ReturnType(*func)(Args...)>
struct AltFuncWrapper<ReturnType(*)(Args...), func> {
    ...
};
#define MAKE_WRAPPER(func) AltFuncWrapper<decltype(&func), func>{}

The full solution is here on Compiler Explorer.

It really is just an amalgamation of @Dani's solution and the C++11 template details from the other question.

Bryce Schober
  • 130
  • 10