如何为成员函数创建类似模板的命名空间

how to create templated-like namespace for member functions

我目前正在尝试定义一个 namespace/struct,它包含存储特定实现的函数指针(假设一个结构包含多个函数)。现在一切正常,结构如下:

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 
    }
}

这个 class 包含几个函数,每个函数都必须知道 a 和 b。问题是我必须创建 class 的实例并设置参数 a 和 b,我宁愿忽略它们。 在另一个 class 中,我仅通过获取其功能来使用此 class。即

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 = ...
    }
}

但我想省略每次都创建一个新的 class inctance(从某种意义上说,我在相同的 class 但代码中的另一个地方重复上述行为)。我试图将此 class 模板化为

template<int a, int b>
class foo{
...
}

所以我可以将函数分配为:

this->fun1 = foo<a,b>::bar;

但是我需要在编译时知道 a 和 b,这是不可能的。这些参数在 class foo2 中设置一次。我意识到整体代码可能不干净,我是物理学家,而不是 IT 人员,如您所见。一种方法是将 class foo 的实例存储在 class foo2 中,并为整个 class 初始化一次,并让函数 fun1、fun2... 可以通过引用访问那些指针,但我正在寻找是否有另一种方法(可能是像 class 这样的模板,我不需要在编译时知道这些值)。 此外,我无法在此处粘贴整个代码,因为它在多个文件中包含数千行代码,并且很难描述代码的作用。我感谢任何帮助,如果这可能是一个愚蠢或微不足道的问题,我深表歉意(我严格来说不是从事 IT 工作,我是一名物理学家;))

您可以在 foo 构造函数中创建 lambda,其中 ab 的值是已知的。

然后您还可以捕获 this 以使用成员变量(以防它们在 lambda 创建和调用之间发生变化)。

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->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 或其他库已经有很多支持此类操作的代码。