C++基于函数名称动态创建函数的实现?

发布于 2025-02-10 20:30:33 字数 688 浏览 1 评论 0原文

我有多个具有相似实现的功能。唯一的区别是他们调用不同的呼叫,基本上基于下面的函数名称。

// A.h
class A : public ParentA
{
  public:
    explicit A(B& b);
    ~A() override = default;

    // accessors
    C does_same_thing1() const;
    C does_same_thing2() const;
    C does_same_thing3() const;
    // ...
}
// A.cpp
C A::does_same_thing1() const
{
    ...
    return xyz.values().thing1();
}

C A::does_same_thing2() const
{
    ...
    return xyz.values().thing2();
}

C A::does_same_thing3() const
{
    ...
    return xyz.values().thing3();
}

我想知道是否有一种动态填写几乎相同的功能的方法,除了他们称之为的登录器(thing1(),thing2()和thing 3(),这实际上不止一次发生,而不仅仅是在返回行上)基于其功能名称。在C ++中可以吗?

谢谢!

I have multiple functions that have long and similar implementations. The only difference is they call different calls, which is basically based on the function name like below.

// A.h
class A : public ParentA
{
  public:
    explicit A(B& b);
    ~A() override = default;

    // accessors
    C does_same_thing1() const;
    C does_same_thing2() const;
    C does_same_thing3() const;
    // ...
}
// A.cpp
C A::does_same_thing1() const
{
    ...
    return xyz.values().thing1();
}

C A::does_same_thing2() const
{
    ...
    return xyz.values().thing2();
}

C A::does_same_thing3() const
{
    ...
    return xyz.values().thing3();
}

I wonder if there's a way to dynamically fill out the functions that are almost the same except the accessors they call (thing1(), thing2(), and thing3(), and this actually happens more than once, not just on the return line) based on their function names. Would this be possible in C++?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吾性傲以野 2025-02-17 20:30:33

您可以编写一个功能模板,然后让呼叫者选择要返回的内容:

template <typename F>
auto foo(F f) {
     ...
     return f(xyz.values());
}

详细信息取决于您从问题中遗漏的详细信息。例如,xyz.values()的类型是否可供呼叫者使用?另外,您必须让呼叫者选择f或编写包装器:

 auto does_same_thing1() {
      foo([](auto& x) { return x.thing1(); }
 }
 // ... and same for the others

You can write one function template and let the caller choose what is to be returned:

template <typename F>
auto foo(F f) {
     ...
     return f(xyz.values());
}

Details depend on details you left out from the question. For example, is the type of xyz.values() available to the caller? Also, it is up to you to let the caller pick f or write wrappers:

 auto does_same_thing1() {
      foo([](auto& x) { return x.thing1(); }
 }
 // ... and same for the others
悲喜皆因你 2025-02-17 20:30:33

一些选项是:

  • 使用抽象并覆盖所需的零件。
  • 使用lambas并通过您的需要的功能。
  • 使用模板函数是上面两个的混合,但是我会让其他人解释这一点。

创建基类

class Base
{
protected:
    int value;

public:
    virtual void differentFunction(int mathThing) = 0;
    void longFunction()
    {
        value = 0;
        std::cout << "I do a lot of steps" << std::endl;

        std::cout << "Step 1" << std::endl;
        value++;

        std::cout << "Step 2" << std::endl;
        value++;

        std::cout << "Step 3" << std::endl;
        value++;

        std::cout << "Step 4" << std::endl;
        value++;

        std::cout << "Step 5" << std::endl;
        value++;

        std::cout << "Step 6" << std::endl;

        //And finally I do a unique thing
        differentFunction(3);
        std::cout << "Resulting value: " << value << std::endl;
    }

    void longLamdaFunction(std::function<void(int& value, int mathThing)> mathFunction)
    {
        value = 0;
        std::cout << "I do a lot of steps" << std::endl;

        std::cout << "Step 1" << std::endl;
        value++;

        std::cout << "Step 2" << std::endl;
        value++;

        std::cout << "Step 3" << std::endl;
        value++;

        std::cout << "Step 4" << std::endl;
        value++;

        std::cout << "Step 5" << std::endl;
        value++;

        std::cout << "Step 6" << std::endl;

        //And finally I do a unique thing
        mathFunction(value, 3);
        std::cout << "Resulting value: " << value << std::endl;
    }
};

创建一个覆盖类创建

class Derived1 : public Base
{
public:
    void differentFunction(int mathThing) override
    {
        std::cout << "I multiply the value" << std::endl;
        value *= mathThing;
    }

};

不同的覆盖类示例,您也可以在此处查看lambda示例

class Derived2 : public Base
{
public:
    void differentFunction(int mathThing) override
    {
        std::cout << "I divide the value" << std::endl;
        value /= mathThing;
    }

};

使用

int main()
{
    Derived1 d1;
    Derived2 d2;

    std::cout << "\nUsing multiple interface\n";
    d1.longFunction();

    std::cout << "\nUsing divide interface\n";
    d2.longFunction();

    std::cout << "\nUsing add lamda\n";
    //I now add them
    auto addFunction = [](int& x, int y) -> void { x += y; };
    d1.longLamdaFunction(addFunction);

    std::cout << "\nUsing subtract lamda\n";
    //I now subtract them
    auto subtractFunction = [](int& x, int y) -> void { x -= y; };
    d1.longLamdaFunction(subtractFunction);
}

Some options are:

  • Using an abstract and overriding the parts you require.
  • Using lambas and passing in the functions your require.
  • Using template functions is kind of a mix of the two above, but I'll let someone else explain that one.

Create your base class

class Base
{
protected:
    int value;

public:
    virtual void differentFunction(int mathThing) = 0;
    void longFunction()
    {
        value = 0;
        std::cout << "I do a lot of steps" << std::endl;

        std::cout << "Step 1" << std::endl;
        value++;

        std::cout << "Step 2" << std::endl;
        value++;

        std::cout << "Step 3" << std::endl;
        value++;

        std::cout << "Step 4" << std::endl;
        value++;

        std::cout << "Step 5" << std::endl;
        value++;

        std::cout << "Step 6" << std::endl;

        //And finally I do a unique thing
        differentFunction(3);
        std::cout << "Resulting value: " << value << std::endl;
    }

    void longLamdaFunction(std::function<void(int& value, int mathThing)> mathFunction)
    {
        value = 0;
        std::cout << "I do a lot of steps" << std::endl;

        std::cout << "Step 1" << std::endl;
        value++;

        std::cout << "Step 2" << std::endl;
        value++;

        std::cout << "Step 3" << std::endl;
        value++;

        std::cout << "Step 4" << std::endl;
        value++;

        std::cout << "Step 5" << std::endl;
        value++;

        std::cout << "Step 6" << std::endl;

        //And finally I do a unique thing
        mathFunction(value, 3);
        std::cout << "Resulting value: " << value << std::endl;
    }
};

Create an overriding class

class Derived1 : public Base
{
public:
    void differentFunction(int mathThing) override
    {
        std::cout << "I multiply the value" << std::endl;
        value *= mathThing;
    }

};

Create a different overriding class

class Derived2 : public Base
{
public:
    void differentFunction(int mathThing) override
    {
        std::cout << "I divide the value" << std::endl;
        value /= mathThing;
    }

};

Example on use, you can see the Lambda example here too

int main()
{
    Derived1 d1;
    Derived2 d2;

    std::cout << "\nUsing multiple interface\n";
    d1.longFunction();

    std::cout << "\nUsing divide interface\n";
    d2.longFunction();

    std::cout << "\nUsing add lamda\n";
    //I now add them
    auto addFunction = [](int& x, int y) -> void { x += y; };
    d1.longLamdaFunction(addFunction);

    std::cout << "\nUsing subtract lamda\n";
    //I now subtract them
    auto subtractFunction = [](int& x, int y) -> void { x -= y; };
    d1.longLamdaFunction(subtractFunction);
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文