C ++非类型模板模板到函数指针/ ref

时间:2017-03-24 02:52:43

标签: c++ templates

在C ++ 11中是否可以这样?我想作为非类型模板参数传入一个模板化的函数指针/ ref:

template <template <typename ... TRest> void (*request_suffix)(ATCommander&, TRest...)>
struct command_helper
{
    template <class ...TArgs>
    static void request(ATCommander& atc, TArgs...args)
    {
        command_base::prefix(atc);
        request_suffix(atc, args...);
    }
};

具体来说,request_suffix的用法是什么?如果是这样,是否也可以转储TArgs的东西?

我打算做一些类似的事情:

// dummy example code, but very closely representative of the kind
// of thing we'll be doing
void specific_request_suffix(ATCommander& atc, const char* p1, int p2)
{
    cout << p1;
    cout << p2;
}

typedef command_helper<specific_request_suffix> command;

command::request(atc, "test param1", 7); // or similar

重要的是,在发出命令:: request时,不需要特定的specific_request_suffix引用。此外,我在嵌入式环境中,因此std :: function不一定可用

1 个答案:

答案 0 :(得分:2)

我使用decltype来推断类型。它看起来像一个黑客,但令人惊讶的是它有效。请参阅以下实施:

void specific_request_suffix(ATCommander& atc, const char* p1, int p2)
{
    cout << p1;
    cout << p2;
}

template<typename T, T *t, typename... Args>
    struct command_helper
    {
        static T *func_ptr;
        static void Request(ATCommander &cmd, Args... args)
        {
            func_ptr(cmd, args...);
        }
    };

template<typename T, T *t, typename... Args>
    T *command_helper<T, t, Args...>::func_ptr = t;

template<typename T, T *t, typename... Args>
    command_helper<T, t, Args...> infer_command_helper(void(*f)(ATCommander&, Args...)) {}

template<typename T, T *t>
    struct command_type
    {
        using type = decltype(infer_command_helper<T, t>(t));
    };

using command = command_type<decltype(specific_request_suffix), specific_request_suffix>::type;

void Task()
{
    ATCommander cmd = 5;
    command::Request(cmd, "h", 10);
    cout << endl;
}

请注意,函数名称必须在命令类型using声明中使用两次。我不知道如何避免它:(

This回答说无法从非类型模板参数推断出类型:

  

因为您在询问基于纯类模板的解决方案   没有宏定义的帮助,答案很简单:as   目前(2014年12月,C ++ 14),这是不可能的。

     

WG21 C ++标准已经确定了这个问题   委员会作为一种需要,有几个建议让模板   自动推断非类型模板参数的类型。

由于我们需要从函数指针中获取函数类型以简化命令声明,因此我倾向于得出结论,直到下一语言标准才能实现。

之前的尝试

这是我的第一次尝试,但它并不能满足所有要求。把它留在这里以防它对某人有用。

template <typename... Rest>
struct command_helper
{
    using TFunc = std::function<void(ATCommander&, Rest...)>;

    static void request(ATCommander &cmd, TFunc func, Rest... rest)
    {
        func(cmd, rest...);
        cout << "Hello in template " << endl;
    }
};

现在您可以按如下方式使用它:

using ATCommander = int;

auto f=[](ATCommander& cmd, int version, double d)
{
    cout << "In lambda " << cmd << " version " << version << " d= " << d;
};

ATCommander cmd = 5;
command_helper<int, double>::request(cmd, f, 1, 0.5);