如何解决如何拥有指向泛型 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
,可变参数不起作用。
请注意,我不能直接使用 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 举报,一经查实,本站将立刻删除。