提问人:Qant123 提问时间:1/7/2022 更新时间:1/7/2022 访问量:103
如何为成员函数创建类似模板的命名空间
how to create templated-like namespace for member functions
问:
我目前正在尝试定义一个命名空间/结构,其中包含存储特定实现的函数指针(假设包含多个函数的结构)。目前,以下结构一切正常:
class foo{
int a;
int b;
public:
explicit foo(int _a, int _b) : a(_a), b(_b) {};
std::function<int(int)> bar(int num) = [=](int num) -> int{
// here I need to know a and b
//do something with num and return
}
}
此类包含多个函数,每个函数都必须知道 a 和 b。问题是我必须创建类的实例并设置参数 a 和 b,我宁愿省略它们。 在另一个类中,我只通过获取其函数来使用该类。即
class foo2{
//some other parameters
int a, b;
std::function<...> fun1, fun2,...;
public:
foo2(int a, int b, ....){this->a = a; this->b = b;};
setFuncs(){
foo instance(a, b);
this->fun1 = [instance](int num){ return instance.bar(num);}
this->fun2 = ...
}
}
但我想省略每次都创建一个新的类 inctance(从某种意义上说,我在同一类中重复上述行为,但在代码中的另一个位置)。我试图将这个类模板化为
template<int a, int b>
class foo{
...
}
因此,我可以将功能分配为:
this->fun1 = foo<a,b>::bar;
但是我需要在编译时知道 a 和 b,这是不可能的。这些参数在类 foo2 中设置一次。正如你所看到的,我意识到整体代码可能并不干净,我是一名物理学家,而不是 IT 人员。一种方法是将 foo 类的实例存储在类 foo2 中,并为整个类初始化一次,并让函数 fun1、fun2 ,...可以通过引用这些指针进行访问,但我正在寻找是否有另一种方法(也许是像类这样的模板,我不需要在编译时知道值)。 此外,我无法在此处粘贴整个代码,因为它在多个文件中包含数千行,并且描述代码的作用非常困难。如果这可能是一个愚蠢或微不足道的问题,我很感激任何帮助,并表示歉意(我不严格地在 IT 部门工作,我是一名物理学家;))
答:
您可以在构造函数中创建 lambda,其中 和 的值是已知的。foo
a
b
然后,您还可以捕获以使用成员变量(以防它们在 lambda 创建和调用之间更改)。this
class foo
{
int a;
int b;
public:
// No need for explicit since this isn't a "conversion" constructor
foo(int a, int b) : a(a), b(b)
{
bar = [this](int x)
{
// Use the argument together with this->a and this->b...
return some_value;
};
}
std::function<int(int)> bar;
};
评论
this
由于您希望某些输入数据比单个函数调用保留更长的时间,因此除非它是完全编译时的数据,否则运行时状态是不可避免的。问题是你希望如何封装这些数据 - 不同的方法会产生非常不同的(主观)感觉,即它们的便利性。
根据您的使用示例:
this->fun1 = foo<a,b>::bar;
如果你想避免状态(或者更确切地说是封装它),你可以创建一个工厂,为你创建函数:
std::function<int(int)> make_func(int a, int b)
{
return [=](int x){ return actual_function(a, b, x); };
}
this->fun1 = make_func(a, b); // now std::function will hold lambda's captured state
这个主题通常被称为部分应用程序,我猜 boost 或其他库已经有很多支持此类操作的代码。
评论
a
b
std::function
评论
std::function