1. ホーム
  2. c++

[解決済み】1つのクラスでメンバ関数を持つジェネリックstd::functionオブジェクトを使用する

2022-04-08 21:04:18

質問

あるクラスについて、同じクラスのメンバ関数への関数ポインタを1つの map 格納 std::function オブジェクトを作成します。しかし、このコードでは冒頭で失敗してしまいます。

#include <functional>

class Foo {
    public:
        void doSomething() {}
        void bindFunction() {
            // ERROR
            std::function<void(void)> f = &Foo::doSomething;
        }
};

受け取る error C2064: term does not evaluate to a function taking 0 argumentsxxcallobj というエラーと、奇妙なテンプレートのインスタンス化エラーとが混在しています。現在、私はWindows 8とVisual Studio 2010/2011で作業していますが、Win 7とVS10でも失敗しています。このエラーは、私が従っていないいくつかの奇妙なC++のルールに基づいている必要があります。

解決方法を教えてください。

非静的メンバ関数は、オブジェクトで呼び出す必要があります。つまり、常に暗黙のうちにこのポインタを引数として渡します。

なぜなら、あなたの std::function シグネチャでは、関数が引数を取らないことを指定しています ( <void(void)> ) の場合は、必ず バインド は、最初の(そして唯一の)引数です。

std::function<void(void)> f = std::bind(&Foo::doSomething, this);

関数をパラメータで束縛する場合は、プレースホルダを指定する必要があります。

using namespace std::placeholders;
std::function<void(int,int)> f = std::bind(&Foo::doSomethingArgs, this, std::placeholders::_1, std::placeholders::_2);

あるいは、あなたのコンパイラがC++11のラムダをサポートしている場合。

std::function<void(int,int)> f = [=](int a, int b) {
    this->doSomethingArgs(a, b);
}

(手元にC++11が使えるコンパイラがないので 今すぐ ということで、こちらは確認できません)