闭包作为 C++ 中的参数和 return 类型
closure as argument and return type in C++
我努力实现一个 class 方法,该方法 returns 一个捕获 this
的闭包(在示例 Foo::f1
中)。这个想法是将它用作 Bar
.
中的一种回调
第一个障碍是我没有弄清楚如何在 using
语句中指定闭包类型。
#include <iostream>
class Foo {
public:
Foo() = default;
~Foo() = default;
// don't know what the correct type specification is
//using fptr = [](int)->int;
//using fptr = int operator()(int);
//using fptr = int (*)();
typedef int (*fptr)(int);
fptr f1(void) {
return [this](int k)->int { return k * this->x_; };
}
private:
int x_ = 2;
};
class Bar {
public:
Bar() = default;
~Bar() = default;
void setfun(Foo::fptr f) { f_ = f; }
void callfun() {
std::cout << "result = " << f_(8) << std::endl;
}
private:
Foo::fptr f_;
};
int main(int, char **) {
Foo foo;
Bar bar;
bar.setfun(foo.f1());
bar.callfun();
return 0;
}
vg
将 f1
函数标记为 returning auto
:
auto f1(void)
{
return [this](int k)->int { return k * this->x_; };
}
然后你可以从 Bar
class 模板制作,并在实例化时
使用 decltype
得到 return 类型的 f1
:
template<class F>
class Bar {
};
Foo foo;
Bar< decltype( std::declval<Foo>().f1() ) > bar;
因为你将 this
捕获到 lambda,它是非无状态的 lambda,不能默认构造,你不能只将 F
存储为普通成员变量。
为避免此问题,您可以使用智能指针来存储 F
,例如 unique_ptr
:
template<class F>
class Bar {
void setfun(F f) { f_ = std::make_unique<F>(f); }
std::unique_ptr<F> f_;
};
完整代码为:
class Foo {
public:
Foo() = default;
~Foo() = default;
auto f1(void)
{
return [this](int k)->int { return k * this->x_; };
}
private:
int x_ = 2;
};
template<class F>
class Bar
{
public:
Bar() = default;
~Bar() = default;
void setfun(F f) { f_ = std::make_unique<F>(f); }
void callfun()
{
std::cout << "result = " << (*f_)(8) << std::endl;
}
private:
std::unique_ptr<F> f_;
};
int main(int, char **) {
Foo foo;
Bar< decltype( std::declval<Foo>().f1() ) > bar;
bar.setfun(foo.f1());
bar.callfun();
我努力实现一个 class 方法,该方法 returns 一个捕获 this
的闭包(在示例 Foo::f1
中)。这个想法是将它用作 Bar
.
第一个障碍是我没有弄清楚如何在 using
语句中指定闭包类型。
#include <iostream>
class Foo {
public:
Foo() = default;
~Foo() = default;
// don't know what the correct type specification is
//using fptr = [](int)->int;
//using fptr = int operator()(int);
//using fptr = int (*)();
typedef int (*fptr)(int);
fptr f1(void) {
return [this](int k)->int { return k * this->x_; };
}
private:
int x_ = 2;
};
class Bar {
public:
Bar() = default;
~Bar() = default;
void setfun(Foo::fptr f) { f_ = f; }
void callfun() {
std::cout << "result = " << f_(8) << std::endl;
}
private:
Foo::fptr f_;
};
int main(int, char **) {
Foo foo;
Bar bar;
bar.setfun(foo.f1());
bar.callfun();
return 0;
}
vg
将 f1
函数标记为 returning auto
:
auto f1(void)
{
return [this](int k)->int { return k * this->x_; };
}
然后你可以从 Bar
class 模板制作,并在实例化时
使用 decltype
得到 return 类型的 f1
:
template<class F>
class Bar {
};
Foo foo;
Bar< decltype( std::declval<Foo>().f1() ) > bar;
因为你将 this
捕获到 lambda,它是非无状态的 lambda,不能默认构造,你不能只将 F
存储为普通成员变量。
为避免此问题,您可以使用智能指针来存储 F
,例如 unique_ptr
:
template<class F>
class Bar {
void setfun(F f) { f_ = std::make_unique<F>(f); }
std::unique_ptr<F> f_;
};
完整代码为:
class Foo {
public:
Foo() = default;
~Foo() = default;
auto f1(void)
{
return [this](int k)->int { return k * this->x_; };
}
private:
int x_ = 2;
};
template<class F>
class Bar
{
public:
Bar() = default;
~Bar() = default;
void setfun(F f) { f_ = std::make_unique<F>(f); }
void callfun()
{
std::cout << "result = " << (*f_)(8) << std::endl;
}
private:
std::unique_ptr<F> f_;
};
int main(int, char **) {
Foo foo;
Bar< decltype( std::declval<Foo>().f1() ) > bar;
bar.setfun(foo.f1());
bar.callfun();