在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不一定可用
答案 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);