如何避免使用已知函数参数的 lambda 函数?
How to avoid lambda functions with a known function parameter?
在下面的代码中,我有一个名为 data
的变量。它在自身内部包含一个函数,以便稍后调用它们。假设 data
是在另一个库中定义的,我无法更改它的类型。我为它的每个成员分配一个模板函数,其中该函数的一部分是已知的 (s3
),并且在调用它时必须给出一部分 (true
)。我不能通过这样的东西:
data[0]=test_func(?,s3); // error
相反,我必须向它传递一个 lambda 函数:
data[0]=[](bool b){test_func(b,s3);}; // ok
但是 lambda 函数看起来并不整洁,尤其是当我们有一个包含 100 个这样的赋值的数组时。有没有办法通过以任何方式更改 test_func
来避免 lambda 函数?即使在 test_func
中使用 lambda 对我来说也可以,因为它只写了一次。
#include <iostream>
#include <functional>
template<typename F>
void test_func(bool b,F f)
{
if(b)
f();
}
void s1()
{
std::cout<<"s1 \n";
}
void s2()
{
std::cout<<"s2 \n";
}
void s3()
{
std::cout<<"s3 \n";
}
int main()
{
test_func(true,s1);
test_func(true,s2);
test_func(false,s1);
test_func(true,s2);
/////////////////
std::function<void(bool)> data[100];
// data=test_func(?,s3); // error
data[0]=[](bool b){test_func(b,s3);}; // ok
data[0](true);
return 0;
}
如果您想像 templates
一样完全避免 lambda
函数,您可以使用函数式(class 和 operator()
):
typedef void (&F)(void);
class TestFunc {
F f;
public:
TestFunc(const F f) : f(f) {}
void operator()(bool B) const {
if(B) f();
}
};
用TestFunc(s3)
赋值。只需 typedef
F
到函数类型,不需要模板:
typedef void (&F)(void);
并完全删除模板 - 如果可能的话,我通常更喜欢更少的模板,但这就是品味。只有当您需要不同的函数签名支持时,才会真正需要模板。
要使用标准库功能,只需更改 typedef
:
typedef std::function<void(void)> F;
您可以在辅助函数中创建 lambda:
#include <iostream>
#include <string>
#include <functional>
#include <vector>
template<typename F>
void test_func(bool b,F f) {
if(b) {
f();
}
}
std::function<void(bool)> wrap_function(const std::function<void(void)> &f) {
return [f](bool b){test_func(b,f);};
}
void s1() {
std::cout<<"s1 \n";
}
int main() {
std::vector<std::function<void(bool)>> data;
data.push_back(wrap_function(s1));
data[0](true);
}
并且您应该使用 std::vector
、std::array
或其他标准容器而不是 std::function<void(bool)> data[100]
如果每个 s_n
都是具有相同签名的常规函数,您可以只从 test_func
中删除 f
参数,而是将函数本身作为模板参数传递。
template<void(&f)()>
void test_func(bool b)
{
if(b)
f();
}
并像这样使用:
data[0] = test_func<s1>;
[temp.param/4] 明确允许函数指针和引用作为模板非类型参数:
A non-type template-parameter shall have one of the following
(optionally cv-qualified) types:
[...]
- pointer to object or pointer to function,
- lvalue reference to object or lvalue reference to function,
在下面的代码中,我有一个名为 data
的变量。它在自身内部包含一个函数,以便稍后调用它们。假设 data
是在另一个库中定义的,我无法更改它的类型。我为它的每个成员分配一个模板函数,其中该函数的一部分是已知的 (s3
),并且在调用它时必须给出一部分 (true
)。我不能通过这样的东西:
data[0]=test_func(?,s3); // error
相反,我必须向它传递一个 lambda 函数:
data[0]=[](bool b){test_func(b,s3);}; // ok
但是 lambda 函数看起来并不整洁,尤其是当我们有一个包含 100 个这样的赋值的数组时。有没有办法通过以任何方式更改 test_func
来避免 lambda 函数?即使在 test_func
中使用 lambda 对我来说也可以,因为它只写了一次。
#include <iostream>
#include <functional>
template<typename F>
void test_func(bool b,F f)
{
if(b)
f();
}
void s1()
{
std::cout<<"s1 \n";
}
void s2()
{
std::cout<<"s2 \n";
}
void s3()
{
std::cout<<"s3 \n";
}
int main()
{
test_func(true,s1);
test_func(true,s2);
test_func(false,s1);
test_func(true,s2);
/////////////////
std::function<void(bool)> data[100];
// data=test_func(?,s3); // error
data[0]=[](bool b){test_func(b,s3);}; // ok
data[0](true);
return 0;
}
如果您想像 templates
一样完全避免 lambda
函数,您可以使用函数式(class 和 operator()
):
typedef void (&F)(void);
class TestFunc {
F f;
public:
TestFunc(const F f) : f(f) {}
void operator()(bool B) const {
if(B) f();
}
};
用TestFunc(s3)
赋值。只需 typedef
F
到函数类型,不需要模板:
typedef void (&F)(void);
并完全删除模板 - 如果可能的话,我通常更喜欢更少的模板,但这就是品味。只有当您需要不同的函数签名支持时,才会真正需要模板。
要使用标准库功能,只需更改 typedef
:
typedef std::function<void(void)> F;
您可以在辅助函数中创建 lambda:
#include <iostream>
#include <string>
#include <functional>
#include <vector>
template<typename F>
void test_func(bool b,F f) {
if(b) {
f();
}
}
std::function<void(bool)> wrap_function(const std::function<void(void)> &f) {
return [f](bool b){test_func(b,f);};
}
void s1() {
std::cout<<"s1 \n";
}
int main() {
std::vector<std::function<void(bool)>> data;
data.push_back(wrap_function(s1));
data[0](true);
}
并且您应该使用 std::vector
、std::array
或其他标准容器而不是 std::function<void(bool)> data[100]
如果每个 s_n
都是具有相同签名的常规函数,您可以只从 test_func
中删除 f
参数,而是将函数本身作为模板参数传递。
template<void(&f)()>
void test_func(bool b)
{
if(b)
f();
}
并像这样使用:
data[0] = test_func<s1>;
[temp.param/4] 明确允许函数指针和引用作为模板非类型参数:
A non-type template-parameter shall have one of the following (optionally cv-qualified) types:
[...]
- pointer to object or pointer to function,
- lvalue reference to object or lvalue reference to function,