内联 lambda 调用模板函数

问题描述 投票:0回答:1

我希望有一个模板方法,它接收数据并使用 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);
}
c++ templates optimization lambda c++17
1个回答
0
投票

是的,这是可能的,但是

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 约束,或者您可以不限制函数。

© www.soinside.com 2019 - 2024. All rights reserved.