c++ - 使用另一个函数作为类中的参数调用函数
问题描述
我试图构建代码来传递要在另一个函数中使用的函数。下面是我尝试过的代码,它在函数之外工作(所以如果我删除与类 Foo 相关的所有内容,它会工作),但我不知道如何让它在类本身内工作。如何在类中传递一个函数?我尝试了this->part1_math_class
,Foo::part1_math_class
和part1_math_class
,没有一个工作。
// Example program
#include <iostream>
#include <string>
#include <stdint.h>
#include <functional>
int64_t loop(std::string partialMath, std::function<int64_t(std::string)> recurse)
{
while (partialMath.find("(") != std::string::npos)
{
auto posClose = partialMath.find(")");
auto posOpen = partialMath.rfind("(", posClose);
std::string sub = partialMath.substr(posOpen + 1, posClose - posOpen - 1);
int64_t resultInner = loop(sub, recurse);
partialMath.replace(posOpen, sub.size() + 2, std::to_string(resultInner));
}
return recurse(partialMath);
}
int64_t part1_math(std::string math)
{
return 0;
}
int64_t part2_math(std::string math)
{
return 1;
}
class Foo {
public:
Foo() { }
int64_t loop_class(std::string partialMath, std::function<int64_t(std::string)> recurse)
{
while (partialMath.find("(") != std::string::npos)
{
auto posClose = partialMath.find(")");
auto posOpen = partialMath.rfind("(", posClose);
std::string sub = partialMath.substr(posOpen + 1, posClose - posOpen - 1);
int64_t resultInner = loop_class(sub, recurse);
partialMath.replace(posOpen, sub.size() + 2, std::to_string(resultInner));
}
return recurse(partialMath);
}
int64_t part1_math_class(std::string math)
{
return 2;
}
int64_t part2_math_class(std::string math)
{
return 3;
}
int64_t runLoop()
{
return loop_class("(1 + 2)", Foo::part1_math_class);
}
};
int main()
{
std::cout << loop("(1 + 2)", part1_math) << std::endl; // this one works
Foo bar;
std::cout << bar.runLoop() << std::endl; // this one does not even compile
return 0;
}
解决方案
关于
int64_t runLoop()
{
return loop_class("(1 + 2)", Foo::part1_math_class);
}
Foo::part1_math_class()
std::function<int64(std::string)>
当使用正确的对象调用时,具有匹配的签名。在这种情况下,this
将是指向预期对象的指针。因此,它必须以某种方式被“欺骗”到调用中。
一种简单的方法是使用仿函数而不是函数。仿函数是一个重载的类,operator()
并且可以像函数一样工作,但具有额外的上下文。
std::function参数可以接受函子和函数。
恕我直言,编写仿函数的最简单方法是lambda:
int64_t runLoop()
{
return loop_class("(1 + 2)",
[this](std::string math) { return part1_math_class(math); });
}
this
被捕获。签名匹配,因为参数是兼容的,并且返回类型是从 lambda 的主体中自动检测并匹配的。
推荐阅读
- amazon-web-services - 如何标记由 AWS Batch 计算环境自动创建的 ECS 集群?
- reactjs - React 和 Web API 是否必须在同一个项目中?
- flutter - 读取蓝牙设备数据并将其返回到 Flutter/Dart 中的代码时出现问题
- docker - 运行 Genie.jl Docker 容器 - ArgumentError:“true”中的 base 10 digit 't' 无效
- javascript - 赛普拉斯 cy.get 返回 HTML 对象,但如果我将 .then(elem) 添加到 cy.get 函数 elem 是一个空的 HTML 对象
- java - 跨JVM在Java中标记消息的时间戳
- install4j - Install4J - 从安装目录中隐藏 .jar 文件?
- java - 降低认知复杂性
- javascript - 在javascript / node js中不使用map,forEach,for ....in函数获取对象值
- python - 使用 cx_oracle 连接数据库但收到 TNS 错误