以 lambda 作为参数的指向成员函数的模板化指针

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

在这篇文章中(为什么成员函数不能用作模板参数?)我看到可以使用指向成员函数的指针作为模板参数,例如:

struct Foo {
    void Bar() { // do something
    }
};
template <typename TOwner, void(TOwner::*func)()>
void Call(TOwner *p) {
    (p->*func)();
}
int main() {
    Foo a;
    Call<Foo, &Foo::Bar>(&a);
    return 0;
} 

但是我想知道如果 Foo::Bar 将 lambda 作为参数,则必须如何调整?那么我必须为“???”添加什么?在以下代码中:

template<typename T>
concept has_call_operator = requires { &T::operator(); };

struct Foo {

    void Bar(has_call_operator auto lambda) {}
};


template <typename TOwner, void(TOwner::*func)(???)>
void CallFoo(TOwner *p) {
    (p->*func)([](){});
}
c++ lambda
1个回答
0
投票

这里的问题是

void Bar(has_call_operator auto lambda)
是一个模板。在实例化它之前你不能获取它的地址。您仅在调用时实例化它,因为您希望从形参推导出模板实参。您可以通过将其包装在可用作
auto
模板参数的 lambda 中来推迟实例化:

#include <functional>

template<typename T>
concept has_call_operator = requires { &T::operator(); };

struct Foo {

    void Bar(has_call_operator auto lambda) {}
};


template <typename TOwner,auto func>
void CallFoo(TOwner *p) {
    std::invoke(func,p,[](){});
}
int main() {
    Foo a;
    CallFoo<Foo,[](Foo* f,auto g){f->Bar(g); }>(&a);
    return 0;
} 

现场演示

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