0

私はc++テンプレートを初めて使用するので、我慢してください。

私がやりたいのは、テンプレート化された関数を利用して、クラスにある種の戦略パターンを実装することです。これが戦略に沿ったものになると思います。

私の理解では、これはファンクターで実現できますが、新しいクラスを導入したくはありません。クラスにインライン戦略関数が必要なだけです。

クラスがあるとしましょうCalculator

Calculator.h

#ifndef CALCULATOR_H
#define CALCULATOR_H


class Calculator
{
    public:
        Calculator();
        virtual ~Calculator();
        typedef void (*Strategy)(int param1, int param2);

        void add(int param1, int param2);

        template<class T>
        void doStrategy(T strategy, int param1, int param2);
    protected:
    private:
};

#endif

Calculator.cpp

Calculator::Calculator()
{
    //ctor
}

Calculator::~Calculator()
{
    //dtor
}

void
Calculator::add(int param1, int param2)
{
    std::cout << "Sum " << param1+param2 << std::endl;
}

template<class T>
void
Calculator::doStrategy(T strategy, int param1, int param2)
{
    strategy(param1,param2);
}

main.cpp

int main()
{
    Calculator calc = Calculator();

    calc.doStrategy<Calulator::Strategy>(calc.add,2,3);
    return 0;
}

これは失敗します

error: no matching function for call to ‘Calculator::doStrategy(<unresolved overloaded function type>, int, int)’|
note: candidate is:|
note: template<class T> void Calculator::doStrategy(T, int, int)|
note:   template argument deduction/substitution failed:|
note:   cannot convert ‘calc.Calculator::add’ (type ‘&lt;unresolved overloaded function type>’) to type ‘void (*)(int, int)’|

==後で編集==

main.cpp

typedef void (Calculator::*Strategy)(int, int);
int main()
{
    Calculator calc = Calculator();
    Strategy strategy = &Calculator::add;

    calc.doStrategy<Strategy>(strategy,2,3);
    return 0;
}

それでも失敗します:

undefined reference to `void Calculator::doStrategy<void (Calculator::*)(int, int)>(void (Calculator::*)(int, int), int, int)'
4

2 に答える 2

5

void add(int param1, int param2)は静的メソッドではないため、オブジェクトのインスタンスで呼び出されます。

typedef void (*Strategy)(int param1, int param2)これは、2つの整数を取り、何も返さないメソッドであるにキャストできないことを意味します。前者には、コードに隠されているが実際には存在するadd暗黙的なものがあるためです。this実際には、メソッドのシグネチャはですvoid (Calculator::*)(int,int)。メソッドをに設定するだけstaticで問題ありません。

メンバー関数へのポインターがどのように機能するかをここで詳しく読むことをお勧めしますが、C ++で作業しているので、ファンクターを利用することをお勧めします。

于 2013-01-06T02:55:52.740 に答える
0

私の英語は短いです...ただコードのままです...

電卓で.h

// this template function use only for calculator's method
// and method must have two arguments.
template<typename Method>
void doStrategy(Method strategy, int param1, int param2)
{
    // argument strategy MUST BE calculator's member function pointer,
    // member function pointer need object, not class
    (this->*strategy)(param1, param2);
}

main.cppで

Calculator cal;

cal.doStrategy(&calculator::add, 2, 3);

..より一般的に..。

電卓で.h

// this template function do not use only for calculator's method
// but method must have two arguments.
template<typename Class, typename Method>
void doStrategy(Class* pObject, Method strategy, int param1, int param2)
{
    // argument strategy MUST BE Class's member function pointer,
    // member function pointer need object, not class
    (pObject->*strategy)(param1, param2);
}

main.cppで

// definition of another member function...
struct foo
{
    void bar(int param1, param2)
    {
        std::cout << "foo::bar " << param1 - param2 << std::endl;
    }
};

int main()
{
    Calculator cal;
    foo test;

    cal.doStrategy(&cal, &calculator::add, 2, 3);
    cal.doStrategy(&test, &foo::bar, 2, 3);

    foo* just_for_member_function = NULL;

    cal.doStrategy(just_for_member_function, &foo::bar, 5, 1); 

    return 0;
}

より一般的には?

次回は...

于 2013-01-06T04:11:42.757 に答える