Объект-оболочка вызова функции C ++ с функцией в качестве аргумента шаблона - PullRequest
0 голосов
/ 04 августа 2020

Я хочу создать вспомогательный объект шаблона, используя только C ++ 11, который можно использовать для C функций.

Я пытаюсь расширить полученный ответ здесь из функции-оболочки в объект-оболочку, чтобы он мог содержать состояние:

#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;
}

Но я получаю следующую ошибку компилятора ( ссылка CE ):

<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;
                                                                   ^

Ответы [ 2 ]

1 голос
/ 04 августа 2020

Ни в одной точке программы вы не указываете Args, и он не может быть выведен, поэтому оказывается, что это пустой пакет. Вы можете захватить аргументы функции, используя частичную специализацию:

template<auto F> class C;
template<typename RV, typename ...Args, RV (*F)(Args...)>
class C<F>
{
    ...
0 голосов
/ 05 августа 2020
Решение

@ Dani побудило меня go вернуться и посмотреть на другой ответ на этот вопрос, который я первоначально упоминал , что привело меня к моему собственному решению:

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>{}

Полное решение - здесь, в Compiler Explorer .

На самом деле это просто смесь решения @ Dani и деталей шаблона C ++ 11 из другого вопроса .

...