微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何拥有指向泛型 lambda 的函数指针?

如何解决如何拥有指向泛型 lambda 的函数指针?

正如标题所说,我如何在代码中表达以下意图?要求是函数指针采用任何类型的参数。由于 id yes no true false equal 1 3 4 0 1 0 2 0 0 0 0 1 3 1 0 1 0 0 ,可变参数不起作用。

https://godbolt.org/z/1E1szT

请注意,我不能直接使用 std::string,因为 auto fp = <the lambda>一个类成员变量。

fp

解决方法

变量模板非常好。
即使你初始化它们的方式也很好。

请注意它是变量的模板,而不是存储模板的变量(不能存在)。

因此,当最终使用它时,一切都崩溃了:

编译器如何知道您指的是无数潜在实例中的哪一个?
很简单,你必须actually tell it

int main(){
    fp<int,int>(1,2);
    fp<char,char>('a','b');
}

当然,手动对 lambda 进行脱糖并获取它的实例would be more practical

struct {
    template <class T1,class T2>
    void operator()(T1 a,T2 b) const {
        std::cout << a << "--" << b << std::endl;
    };
} fp;

遗憾的是,我们不能简单地为 lambda 命名并让编译器自行计算。
为合适的语法集思广益:

struct A = []...;
struct B : []... {
};
using C = []...;
,

您不能拥有这样的模板函数指针,但请记住,lambda 只是语法糖,您可以自己编写类。

class fp {
    template<class AT,class BT>
    void operator()(AT&& a,BT&& b) {
        std::cout << a << "--" << b << std::endl; 
    };
};
class class_with_functionoid_member {
    fp fn_;
};

更通用的版本是您可以将 lambda 作为成员。您必须将 lambda 类型作为类参数。

template<class fnT> 
class class_with_lambda_member {
    fnT fn_;
public:
    class_with_lambda_member(fnT fn) : fn_(std::move(fn)) {}
};

要点是函数指针是一种运行时类型擦除,模板成员函数需要编译时延迟实例化,C++没有办法混合这两个概念。想到的所有解决方法都围绕着在“接口”中显式列出 T1 和 T2` 的所有可能组合,它不与函数指针混合,但可以与函数指针查找对象一起使用。

struct erasable_functions {
    virtual ~erasable_functions(){}
    virtual void operator()(int,int)=0;
    virtual void operator()(int,char)=0;
    virtual void operator()(char,int)=0;
    virtual void operator()(char,char)=0;
};

template<class lambdaT>
struct erased_functions : erasable_functions {
    lambdaT lambda_;
    erased_functions(lambdaT lambda) : lambda_(std::move(lambda)){}
    virtual void operator()(int a,int b) {lambda_(a,b);
    virtual void operator()(int a,char b) {lambda_(a,b);
    virtual void operator()(char a,b);
};
template<class lambdaT>
erased_functions<lambdaT> erase_functions(lambdaT lambda)
{return {std::move(lambda)};}

struct class_with_functionoid_member {
    erasable_functions* functions_;
    class_with_functionoid_member(erasable_functions* functions) : functions_(functions){}
    void operator()(int a,int b) {(*functions_)(a,b);
    void operator()(int a,char b) {(*functions_)(a,b);
    void operator()(char a,b);
};

int main() {
    auto lambda = erase_functions([](auto a,auto b) {
            std::cout << a << "--" << b << std::endl;
        };
    class_with_functionoid_member c(&lambda);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。