【问题标题】:How can I make template codes using member-Function如何使用 member-Function 制作模板代码
【发布时间】:2021-08-23 02:37:04
【问题描述】:
class A
{
public:
    A* m_child;
    A* m_brother;
    int x;
    A(int num) :x{ num } {};
public:
    template<typename Pred, typename...Args>
    void ForFamily(Pred, Args&&... args) {
        if (m_child) Pred(m_child*, std::forward<Args>(args)...);
        if (m_brother) m_brother->Pred(std::forward<Args>(args)...);
    }
    void f(int a, int b) {
        cout << x + a + b;
    }
    void g(int a) {
        cout << a + x;
    }
};

我想制作一个适用于每个 m_child 和 m_brother 的 Template_Func。我怎样才能使它起作用? 我会这样使用它

int main()
{
    A a(1), b(2), c(3);
    a.m_child = &b;
    a.m_brother = &c;

    a.ForFamily(A::f, 1, 2);
    a.ForFamily(A::g, 1);
}

【问题讨论】:

  • @fabian 我编辑了!

标签: c++ class templates


【解决方案1】:

使用成员函数指针作为成员函数的第一个参数。请注意,如果这些成员未初始化,我还向指针添加了默认初始化以避免未定义的行为:

class A
{
public:
    A* m_child {nullptr};
    A* m_brother {nullptr};
    int x;
    A(int num) :x{ num } {};
public:
    template<typename... Args>
    void ForFamily(void (A::*funct)(Args...), Args&&... args)
    {
        if (m_child != nullptr)
        {
            (m_child->*funct)(std::forward<Args>(args)...);
        }
        if (m_brother != nullptr)
        {
            (m_brother->*funct)(std::forward<Args>(args)...);
        }
    }


    void f(int a, int b) {
        cout << x + a + b;
    }
    void g(int a) {
        cout << a + x;
    }
};

int main()
{
    A a(1), b(2), c(3);
    a.m_child = &b;
    a.m_brother = &c;

    a.ForFamily(&A::f, 1, 2);
    a.ForFamily(&A::g, 1);
}

您可能希望将功能放在 A 类之外,例如

    template<typename Funct, typename... Args>
    void ForFamily(Funct funct, Args&&... args)
    {
        if (m_child != nullptr)
        {
            funct(m_child->x, std::forward<Args>(args)...);
        }
        if (m_brother != nullptr)
        {
            funct(m_brother->x, std::forward<Args>(args)...);
        }
    }
...

    a.ForFamily([](int x, int a, int b) { std::cout << (x + a + b);}, 1, 2);
    a.ForFamily([](int x, int a) { std::cout << (x + a);}, 1);

    template<typename Funct, typename... Args>
    void ForFamily(Funct funct, Args&&... args)
    {
        if (m_child != nullptr)
        {
            funct(*m_child, std::forward<Args>(args)...);
        }
        if (m_brother != nullptr)
        {
            funct(*m_brother, std::forward<Args>(args)...);
        }
    }
...

    a.ForFamily([](A& obj, int a, int b) { obj.f(a, b);}, 1, 2);
    a.ForFamily([](A& obj, int a) { obj.g(a);}, 1);

因为这些更灵活。 (请注意,如果我有一个使用 lambda 的真实应用程序,通常我不会费心通过 ForFamily 通过转发传递它们,而只需将它们绑定/硬编码到 lambda。)

【讨论】:

    猜你喜欢
    • 2021-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-22
    • 2014-11-23
    相关资源
    最近更新 更多