将 C++20 模板化 Lambda 传递给函数然后调用它

Guk*_*ki5 3 c++ lambda templates c++20

我试图将模板化 lambda 传递给函数,然后使用模板参数调用它,以启用该函数针对自定义类型的专门化。

但是当我尝试调用 lambda 时,出现此错误:error: invalid operands to binary expression

对于任何想尝试这个的人来说,这里有一个 godbolt 链接: https: //gcc.godbolt.org/z/qYPcea

#include <cstdint>
#include <string>
#include <cstring>

enum class Alignment : uint8_t {
    
    one,
    two,
    four,
    eight
};

template <Alignment alignment, typename T>
static void align(T& pointer)
{
    intptr_t& value = reinterpret_cast<intptr_t&>(pointer);
    value += (-value) & ((uint64_t)alignment - 1);
}

template<typename Lambda, typename T>
static void specialization(Lambda&& lambda, const T& t) 
{
   lambda<Alignment::eight>(t.data(), t.size());
}

int main()
{
    uint8_t buffer[1024];

    void *writeTo = buffer;

    auto lambda = [&] <Alignment alignment> (const void *input, uint32_t inputSize) -> void
    {
        align<alignment>(writeTo);
        writeTo = memcpy(writeTo, buffer, inputSize);
    };
    
    std::string input("helloworld");

    specialization(lambda, input);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

cig*_*ien 6

问题是 lambda 不是类模板,它们只是成员调用运算符 ieoperator()被模板化的常规类。

当为泛型 lambda 推导模板参数时,这种区别并不明显(这是一件非常好的事情)。

因此,在您的示例中,lambda不是类模板,但您使用的语法将用于类,而不是成员函数。

如果您想显式指定 lambda 的模板参数,则需要说明您正在调用 的成员operator()lambda并且需要说明它是一个要消除歧义的模板。

lambda.template operator()<Alignment::eight>(t.data(), t.size());
Run Code Online (Sandbox Code Playgroud)

这是编译的代码版本。

#include <cstdint>
#include <string>
#include <cstring>

enum class Alignment : uint8_t {
    
    one,
    two,
    four,
    eight
};

template <Alignment alignment, typename T>
static void align(T& pointer)
{
    intptr_t& value = reinterpret_cast<intptr_t&>(pointer);
    value += (-value) & ((uint64_t)alignment - 1);
}

template<typename Lambda, typename T>
static void specialization(Lambda&& lambda, const T& t) 
{
   lambda.template operator()<Alignment::eight>(t.data(), t.size());
}

int main()
{
    uint8_t buffer[1024];

    void *writeTo = buffer;

    auto lambda = [&] <Alignment alignment> (const void *input, uint32_t inputSize) -> void
    {
        align<alignment>(writeTo);
        writeTo = memcpy(writeTo, buffer, inputSize);
    };
    
    std::string input("helloworld");

    specialization(lambda, input);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)