6

簡単に言えば、関数オブジェクト/ラムダとメンバー関数を合理化された方法で処理する簡単な/定義された方法はありますか?

私が正しく理解している場合、std::mem_fn を使用する場合、正しい型のオブジェクトを関数呼び出しに渡す必要があります。

Object o;
ftncall std::mem_fun(&Object::function);
ftncall(o);

理想的にはo、おそらく としてその関数オブジェクトに「アタッチ」する方法があるstd::weak_ptrため、 o が削除されたかどうかがわかります。たとえば、次のような漠然としたことを行う方法があったとします。

Object o;
ftncall std::mem_fn(&Object::function, o); // Or maybe std::mem_fn<Object>
ftncall();

さて、明らかに、これは存在しません (私の知る限り)。std::mem_fn の一般性 (および良さ) を失わないように std::mem_fn をラップする方法はありますかo? ::関数?理想的にoperator()は、std::function と同じように使用できます。

現在、私が考えることができる最善の解決策は、次のようなクラスです。

template<class T>
class MemFunWrapper {
public:
    MemFunWrapper(T* t, std::mem_fun funct) : m_t(t), m_function(funct) {}

    std::mem_fun operator*() { return m_function; }
    T* get() { return m_t; }
private:
    T* m_t;
    std::mem_fun m_function;
}

次に、次のように使用できます。

(*MemFunWrapper)(MemFunWrapper->get(), args...);

しかし、それは私にはかなり扱いにくいようです。また、同様の方法で使用できるようにするには、std::function に相当するクラスを作成する必要があります。すでに std::function を使用できるので、それはばかげているようです。理想的には、メンバー関数を呼び出しているのか通常の関数を呼び出しているのかを知らずに、最終製品を使用することもできます。私は多くのことを尋ねていることを知っています-どんな方向でも役に立ちます. どうもありがとう!

4

2 に答える 2

10

C++11 では、通常、これはラムダで行うのが最も簡単です。

std::shared_ptr<Object> o = std::make_shared<Object>();
auto ftncall = [o](){ if (o) o->function(); }
ftncall();

または、共有ライフタイムなし:

Object o;
auto ftncall = [&o](){ o.function(); }
ftncall();

または弱いptrを使用:

std::shared_ptr<Object> o = std::make_shared<Object>();
std::weak_ptr<Object> wo = o;
auto ftncall = [ow](){ if (auto o = wo.lock()) o->function(); }
ftncall();

型消去が必要な場合は、std::function<void()>.

bindC++11 のラムダは、ライブラリ関数に依存しなくても、C++11 とほぼ同じ仕事をすることができます。個人的には、ラムダの方がはるかに読みやすいと思います。

bindC++11 でより良い仕事をすることができるいくつかの状況がありますが、それらは現時点ではコーナーケースです (C++1y では、より多くのコーナーも同様にカットされます)。

于 2013-09-03T14:01:36.460 に答える