【问题标题】:c++ Trouble casting overloaded function: <unresolved overloaded function type>c++ 重载函数转换问题:<未解析的重载函数类型>
【发布时间】:2012-09-06 15:21:00
【问题描述】:

我在超类中有函数,旨在将字符串与内部函数相关联:

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 ‘<unresolved overloaded function type>’ to type ‘void (*)(double)’

我错过了什么?

【问题讨论】:

  • 成员函数不是函数。这行不通。

标签: c++ casting overloading


【解决方案1】:

正如其他人所说,类型不匹配。但是,您可以使用 std::bind 使其工作:

Base::registerInput(
    "Height", 
    std::bind(&SubBase::setHeight, *this, std::placeholders::_1)
);

【讨论】:

  • 也许值得一提的是函数类型应该是std::function&lt;void(double)&gt;...
  • 为了使这个更通用,我尝试了这个和 ForEveR 的答案,最终都得到了与我原来的问题相同的错误消息。
【解决方案2】:

SubBase 不是static,因此它有一个隐式的第一个参数SubBase*(您为其调用成员函数的对象)。因此签名是void (*) (SubBase*, double)。在 C++11 中,您可能(我不完全确定)将其转换为 function&lt;void (SubBase*, double)&gt;

使用 lambda 函数,您可以执行以下操作:

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

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

【讨论】:

  • 这确实很有效 - 扩展它以适用于接受其他数据类型 (int) (Base*) 的函数是否微不足道?
  • 一个方法可以接受的类型通常不止一种,基本类型如 double、int 和 unsigned,但 Base 的子类可以反馈给自身——类似于:[myself](int v){myself->setHeight(v);} [myself](SubBase2 v){myself->setHeight(v);} 有适当的方法,但将它们存储在同一个地图中似乎不符合语言。
  • 没关系 - 我试图太聪明 - 只保留不同输入类型的地图要容易得多。
【解决方案3】:
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-29
    • 1970-01-01
    • 1970-01-01
    • 2012-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多