3

文字列を内部関数に関連付けるように設計されたスーパークラスに関数があります。

class Base
{
    typedef std::function<void(double)> double_v;

    bool registerInput(std::string const& key, double_v const& input) {
        functions[key] = input;
    }

    void setInput(std::string key, double value) {
        auto fit = functions.find(key);
        if (fit == functions.end()) return;

        fit->second(value);
    }

    std::map<std::string, double_v> functions;
}

関数を登録できるサブクラスは、文字列と値でそれらを呼び出すことができるという考えです:

SubBase::SubBase() : Base(){
    Base::registerInput(
        "Height", 
        static_cast<void (*)(double)>(&SubBase::setHeight)
    );
}

void SubBase::setHeight(double h) {
....
}

次に、次のように呼び出すことができます。

subBaseInstance.setInput("Height", 2.0);

ただし、コンパイルすると、次のエラーが発生します。

In constructor ‘SubBase::SubBase()’
error: invalid static_cast from type ‘&lt;unresolved overloaded function type>’ to type ‘void (*)(double)’

私は何が欠けていますか?

4

3 に答える 3

4

他の人が指摘したように、タイプは一致しません。ただし、それを機能させるために使用できますstd::bind

Base::registerInput(
    "Height", 
    std::bind(&SubBase::setHeight, *this, std::placeholders::_1)
);
于 2012-09-06T07:10:10.573 に答える
1

SubBaseは ではないため、 (メンバー関数を呼び出すオブジェクト)staticの暗黙的な最初の引数があります。SubBase*したがって、署名はvoid (*) (SubBase*, double). C++ 11では、おそらく(完全にはわかりませんが)それをにキャストできfunction<void (SubBase*, double)>ます。

ラムダ関数を使用すると、次のことができます。

SubBase::SubBase() : Base(){
    auto myself = this;
    Base::registerInput( 
        "Height",  
        [myself] (double v) { myself->setHeight (v); }
    ); 
} 

void SubBase::setHeight(double h) { 
.... 
} 
于 2012-09-06T07:06:31.960 に答える
1
typedef std::function<void(double)> double_v;

ですfunction-pointer

static_cast<void (*)(double)>(&SubBase::setHeight)

ですmember-function pointer。それらは相互に変換できません。

std::bindこれに使用できます

SubBase::SubBase() : Base(){
    Base::registerInput(
        "Height", 
        std::bind(&SubBase::setHeight, this, std::placeholders::_1)
    );
于 2012-09-06T07:05:33.413 に答える