1

この質問に関連して、それはおそらく過度に単純化されているので、ここでより複雑な例を示します。私がふりをする問題は、次のコードで表されます。

// test3.cpp

using namespace std;

template<typename T>
struct exer
{
    template<typename R, typename... rArgs, typename... pArgs>
    R operator()(R(T::*f)(rArgs...), pArgs&&... args)
    {
       return (t.*f)(forward<pArgs>(args)...);
    }

    T t;
};

struct A
{
    int addition() { return 0; }

    template<typename... Args>
    int addition(int a, Args... args) { return a + addition(args...); }
};

struct B
{
public:
    template<typename... Args>
    int addition(Args&&... args)
    {
       return m_e(&A::addition, forward<Args>(args)...);
    }

private:
    exer<A> m_e;
};

int main()
{
    B b;

    cout << b.addition(1, 2, 3, 4) << endl;
}

ここでのこの問題は、のインスタンス化では、さまざまなオーバーロードが存在するためB::addition、のタイプ&A::additionが不明であるということです。さらに、B::additionどのオーバーロードを使用する必要があるかもわかりません。これは、関数が呼び出されるまでコンパイラを認識しません。ただし、でオーバーロードを使用する必要があることを正しく指定するには、をキャストして正しいオーバーロードにキャストするexer<A>::operator()必要があります。&A::addition

ターゲット関数の正しいオーバーロードのタイプを抽出するにはどうすればよいですか?

4

1 に答える 1

3

質問を変更します。exer次のように、メンバー関数へのポインターの代わりに呼び出し可能なオブジェクトを取得できる場合:

template<typename T>
struct exer
{
    T t;
    template<typename F, typename... pArgs>
    auto operator()(F f, pArgs&&... args)
    -> decltype(f(t, forward<pArgs>(args)...))
    {
       return f(t, forward<pArgs>(args)...);
    }

};

次に、代わりにこれを行うことができます。

struct B
{
public:
    template<typename... Args>
    int addition(Args&&... args)
    {
        struct Invoker {
            auto operator()(A& a, Args&&... args) const
                ->decltype(a.addition(std::forward<Args>(args)...))
            { return a.addition(std::forward<Args>(args)...); }
        };
        return m_e(Invoker(), forward<Args>(args)...);
    }

private:
    exer<A> m_e;
};

これで、正しい選択はA::addition、通常の過負荷解決ルールを使用してコンパイラーによって行われます。

代わりにInvoker、ラムダ式を使用して、繰り返しの一部を減らすことができます。

        return m_e( [](A& a, Args&&... as) {
                      return a.addition(forward<Args>(as)...);
                    },
                    forward<Args>(args)...);
于 2013-03-19T20:00:19.330 に答える