在下面的代码中,我有一个名为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;
}
答案 0 :(得分:2)
如果您想完全避免使用lambda
功能,templates
可以使用功能(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;
答案 1 :(得分:2)
如果每个s_n
都是具有相同签名的常规函数,则只需从f
中删除该test_func
参数,然后将该函数本身作为模板参数传递。
template<void(&f)()>
void test_func(bool b)
{
if(b)
f();
}
并像这样使用:
data[0] = test_func<s1>;
[temp.param/4]明确允许函数指针和引用作为模板非类型参数:
非类型模板参数应具有以下之一 (可选择cv-qualified)类型:
[...]
- 指向对象或指向函数的指针,
- 对对象的左值引用或对函数的左值引用,
答案 2 :(得分:1)
您可以在辅助函数中创建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]