给出一个函数签名(例如来自A 23.03.2018 08:17:00
A 23.03.2018 08:18:00
A 23.03.2018 08:19:00
A 23.03.2018 08:20:00
....
A 23.03.2018 13:55:00
B 23.03.2018 11:17:00
B 23.03.2018 11:18:00
B 23.03.2018 11:19:00
B 23.03.2018 11:20:00
....
B 23.03.2018 13:55:00
参数),我想用该签名创建一个(非内联的)函数,然后调用它。
以下内容应阐明此意图。按照编写的方式,它是无效的,因为标记的行实际上会生成一个空函数指针,而不是空函数:
template
如何在此处创建函数对象?
(旁注:这似乎很奇怪。原因是它是一个通用分析器,它调用{标记为不可内联的)测试函数template <typename Function, typename... Args>
void foo(Args... args) {
Function fn_trivial = {}; //incorrect; should be empty function, not null function
fn_trivial(args...);
}
次来计算平均延迟。可以通过减去具有相同参数的函数调用的延迟(平均而言不执行任何操作)来获得(更好的)测试代码成本。)
答案 0 :(得分:1)
您不能在C ++中创建本地函数。您可以创建本地对象类型并定义/调用其operator()
,也可以使用lambda,但此时最好将其作为真实函数放在外面:
template <typename TypeRet, typename... Args>
TypeRet empty_function(Args... args) {
return TypeRet();
}
template <typename Function, typename... Args>
void foo(Args... args) {
empty_function<decltype( std::declval<Function>()(args...) )>(args...);
}
(请根据需要考虑添加std::forward
。)
请注意,即使标记为不可内联的,任何有价值的编译器也会删除该调用。这是因为即使未内联函数,它也不会执行任何操作,因此可以完全删除。您可以通过多种方式解决此问题,但是使用volatile
变量可移植到Clang,GCC,ICC和MSVC:
#ifdef _MSC_VER
#define NOINLINE __declspec(noinline)
#else
#define NOINLINE __attribute__((noinline))
#endif
template <typename TypeRet, typename... Args>
NOINLINE TypeRet empty_function(Args... args) {
TypeRet volatile a = TypeRet();
return a;
}