3

メンバー関数をテンプレート引数として使用したい場合、Caller型を指定せずにテンプレート化する方法はありますか?

struct Foo
{
    template <typename Caller, void (Caller::*Func)(int)>
    void call(Caller * c) { (c->*Func)(6); }
};

struct Bar
{
    void start() 
    {
        Foo f;
        f.call<Bar, &Bar::printNumber>(this);
               ^^^^  
    }

    void printNumber(int i) { std::cout << i; }
};

int main ()
{
    Bar b;
    b.start();
    return 0;
}

私がしようとすると

template <void (Caller::*Func)(int), typename Caller>
void call(Caller * c) { (c->*Func)(6); }

そしてそれを次のように呼び出します

f.call<&Bar::printNumber>(this);

エラーが発生してCaller is not class...います。

では、コンパイラに Caller 型を推測させる方法はありますか?

4

1 に答える 1

2

いいえ、あなたが望むようではありません。Caller次の場合に推測できます

  1. メンバー関数へのポインターは、テンプレート パラメーターではなくパラメーターでした。例えば:

    template <class Caller>
    void call(Caller * c, void (Caller::*Func)(int)) { (c->*Func)(6); }
    
  2. それは事前に知られていた。たとえば、呼び出しを次のようにすることができます。

    f.arg(this).call<&Bar::printNumber>();
    

    関数は次のcallようになります。

    template <class Arg>
    struct Binder
    {
      template<void (Arg::*Func)(int)>
      void operator()() const {
        ...
      }
    };
    

    関数はarg簡単に記述できます(あなたの場合Binder<Bar>Barから推定されるを返しますthis)。

    あまり便利ではありません、私見。

于 2012-04-19T08:46:56.030 に答える