簡體   English   中英

調用作為模板參數給出的另一個類的成員函數

[英]Calling another class's member function that is given as template parameter

對我要實現的目標的印象:

class Foo
{
    void func1(int parameter);

    Bar<func1>  bar1;

    void some_member(int parameter)
    {
        bar1(parameter);  //should call func1 trough template function object bar1.
    }
};

這有可能嗎? 如果是這樣,我想看看Bar的示例實現。

至於為什么; 我有很多這樣的成員函數,例如func1,都具有相同的簽名。 當要傳遞的參數為0時,應使用先前的非0參數。 我想自動執行此操作,函數對象可以記住該參數並進行0檢查。

要使用指針調用類的不同方法,將如下所示:

class Foo
{
    void (Foo::*bar1)(int);

    void func1(int parameter);
    void func2(int parameter);
    void func3(int parameter);
    ...

    Foo()
    {
        if (condition)
            bar1 = &Foo::func1;
        else if (condition)
            bar1 = &Foo::func2;
        else if (condition)
            bar1 = &Foo::func3;
        ...
    }

    void some_member(int parameter)
    {
        (this->*bar1)(parameter);
    }
};

將其包裝在模板中將類似於以下內容(您不能將實際的方法函數指針作為模板參數傳遞,因為在編譯時它不是常量值):

template<typename T>
struct Bar
{
    typedef void (T::*MethodType)(int);

    T *m_obj;
    MethodType m_method;

    Bar(T *obj)
        : m_obj(obj), m_meth(0)
    {
    }

    Bar& operator=(MethodType rhs)
    {
        m_method = rhs;
        return *this;
    }

    void operator()(int parameter)
    {
        if ((m_obj) && (m_method))
            (m_obj->*m_method)(parameter);
    }
}

class Foo
{
    Bar<Foo> bar1;

    void func1(int parameter);
    void func2(int parameter);
    void func3(int parameter);
    ...

    Foo()
        : bar1(this)
    {
        if (condition)
            bar1 = &Foo::func1;
        else if (condition)
            bar1 = &Foo::func2;
        else if (condition)
            bar1 = &Foo::func3;
        ...
    }

    void some_member(int parameter)
    {
        bar1(parameter);
    }
};

或者,如果您希望調用方指定方法類型:

template<typename T, typename MethodType>
struct Bar
{
    T *m_obj;
    MethodType m_method;

    Bar(T *obj)
        : m_obj(obj), m_meth(0)
    {
    }

    Bar& operator=(MethodType rhs)
    {
        m_method = rhs;
        return *this;
    }

    void operator()(int parameter)
    {
        if ((m_obj) && (m_method))
            (m_obj->*m_method)(parameter);
    }
}

class Foo
{
    Bar<Foo, void (Foo::*)(int)> bar1;
    // or:
    // Bar<Foo, decltype(Foo::func1)> bar1;

    void func1(int parameter);
    void func2(int parameter);
    void func3(int parameter);
    ...

    Foo()
        : bar1(this)
    {
        if (condition)
            bar1 = &Foo::func1;
        else if (condition)
            bar1 = &Foo::func2;
        else if (condition)
            bar1 = &Foo::func3;
        ...
    }

    void some_member(int parameter)
    {
        bar1(parameter);
    }
};

話雖如此,在C ++ 11和更高版本中,請考慮使用std::bind()std::function代替手動模板,例如:

#include <functional>

using std::placeholders::_1;

class Foo
{
    std::function<void(int)> bar1;

    void func1(int parameter);
    void func2(int parameter);
    void func3(int parameter);
    ...

    Foo()
    {
        if (condition)
            bar1 = std::bind(&Foo::func1, this, _1);
        else if (condition)
            bar1 = std::bind(&Foo::func2, this, _1);
        else if (condition)
            bar1 = std::bind(&Foo::func3, this, _1);
        ...
    }

    void some_member(int parameter)
    {
        bar1(parameter);
    }
};

我認為您想要一個小的助手,它將根據您先前的參數進行檢查並采取行動。

下面只是一個想法,您可能需要對其進行擴展。.由於在這種情況下無法將值恢復為零。

struct sample
{
   void func1(int data)
   {
      std::cout << "Func 1 , data = " << data << std::endl;
   }
   void func2(int data)
   {
      std::cout << "Func 2 , data = " << data << std::endl;
   }
};


void invoker(std::function<void(int)> call, int param)
{
   static int _param;

   if (param) _param = param;

   call(_param);
}

int main()
{

   sample s;

   using namespace std::placeholders;
   invoker(std::bind(&sample::func1, &s, _1),1);
   invoker(std::bind(&sample::func2, &s, _1),0);

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM