我希望有一个模板方法,它接收数据并使用 lambda 函数对其进行处理,无论方法本身想要以何种方式执行此操作。但是,我希望内联 lambda 函数,以便编译后的汇编输出最终不会有“调用”汇编指令。这可能吗?
如果 lambda 无法实现,还有其他方法吗?以某种方式使用模板将函数作为模板类型或其他东西传递?
我正在使用 C++17。
下面是我想要实现的目标的示例:
template <typename T>
static inline void Process(const T* p_source1,
const T* p_source2,
T* p_destination,
const int count,
std::function<T (T, T)> processor)
{
for (int i = 0; i < count; i++)
p_destination[i] = processor(p_source1[i], p_source2[i]);
}
void Process_Add(const uint8_t* p_source1,
const uint8_t* p_source2,
uint8_t* p_destination,
const int count)
{
// How to make something like this lambda inline?
auto lambda = [] (uint8_t a, uint8_t b) { return a + b; };
Process<uint8_t>(p_source1, p_source2, p_destination, count, lambda);
}
是的,这是可能的,但是
std::function
使它变得非常不可能,因为调用机制非常复杂,以至于即使在简单的情况下也无法内联。
请参阅了解 std::function 的开销并捕获同步 lambdas
这是使内联更有可能的典型方法:
template <typename T, typename F>
requires (std::invocable<F, const T&, const T&> // optional: C++20 constraint
&& std::convertible_to<std::invoke_result<F, const T&, const T&>, T>)
static inline void Process(const T* p_source1,
const T* p_source2,
T* p_destination,
const int count,
F processor)
{
for (int i = 0; i < count; i++)
p_destination[i] = processor(p_source1[i], p_source2[i]);
}
每个 lambda 表达式都有一个唯一的闭包类型,因此
processor(...)
调用编译时已知的调用运算符。
只要 lambda 表达式相对较短,这使得内联的可能性很大。
您可以使用
std::enable_if_t
模仿 C++20 约束,或者您可以不限制函数。