【问题标题】:std::function expression does not result in a function which accepts 1 Arguementstd::function 表达式不会产生接受 1 个参数的函数
【发布时间】:2014-04-17 22:06:55
【问题描述】:

我正在学习使用 std::function 来传递函数。我从 MSDN 站点获取了代码,它向我展示了如何了解进程是否已启动。

http://pastebin.com/gVkXZC9b

我知道函数 void signal_onProcessStart 不是必需的,我稍后会放大它。

我的问题是我的编译器告诉我 std::function 存在错误。

表达式不会导致接受 1 个参数的函数。

我使用的是德文版的 Visual Studio,所以我翻译了它。我认为错误在英语中的称呼不同。

所有应触发的函数都以“返回值”为空,唯一的参数为 HRESULT*。

问候

编辑:

我做了一个同样错误的小例子:

#include<functional>
#include<iostream>
#include<Windows.h>

using namespace std;

class workingClass
{
private:
    std::function<void(int)> f;
public:
    workingClass(std::function<void(int)> p)
    {
        this->f = p;
    }
    void triggerme(int x)
    {
        this->f(x);
    }
    ~workingClass(){}
};

class managingClass
{
private:
    function<void(int)> f;
    workingClass * ptr;
    int x;
protected:
    void trigger(int x)
    {
        this->f(x);
    }
public:

    managingClass(function<void(int)> f)
    {
        this->f = f;
        function<void(int)> tmp = bind(&managingClass::trigger, this->x);
        ptr = new workingClass(tmp);
        ptr->triggerme(20);
    }
    ~managingClass(){}
};

void triggered(int x)
{
    cout << "it is triggered";
}

int main()
{
    function<void(int)> t = bind(&triggered, 20);
    managingClass temp(t);
    system("pause");
}

文件功能中的ERROR LINE 1149 表达式不会产生接受 1 的函数

【问题讨论】:

  • 你能把代码墙减少到[minimal, but complete test case],然后把它贴在这里而不是粘贴箱吗?并请指出哪一行产生了错误。
  • 查看标记编辑:我想做的一个小例子。

标签: c++ visual-c++ c++11 std std-function


【解决方案1】:

您应该使用placeholders 来达到您的目的。 This 将起作用:

using std::placeholders::_1;

class workingClass
{
private:
    std::function<void(int)> f;
public:
    workingClass(std::function<void(int)> p)
    {
        this->f = p;
    }
    void triggerme(int x)
    {
        this->f(x);
    }
    ~workingClass(){}
};

class managingClass
{
private:
    function<void(int)> f;
    workingClass * ptr;
    int x;
protected:
    void trigger(int x)
    {
        this->f(x);
    }
public:

    managingClass(function<void(int)> f)
    {
        this->f = f;
        function<void(int)> tmp = bind(&managingClass::trigger, this, _1);//, this->x);
                                                                //    ^^
        ptr = new workingClass(tmp);
        ptr->triggerme(20);
    }
    ~managingClass(){}
};

void triggered(int x)
{
    cout << "it is triggered";
}

int main()
{
    function<void(int)> t = bind(&triggered, _1);//, 20);
                                        //   ^^
    managingClass temp(t);
}

【讨论】:

    【解决方案2】:

    你的绑定语句是错误的。

    由于triggermanagingClass 的成员函数,它不能直接存储在std::function&lt;void(int)&gt; 中。需要告诉它应该在类的哪个具体实例(即哪个对象)上调用该函数。

    换句话说,你可以把它想象成一个带有签名void(managingClass*,int)的函数:

    managingClass(function<void(int)> f)
    {
        std::function<void(managingClass*,int)> foo =
            std::mem_fn(&managingClass::trigger);
        // don't worry about the std::mem_fn here too much. It's required
        // to keep the compiler happy, since in C++ member function pointers
        // require different handling than ordinary function pointers,
        // but has no deeper meaning
        foo(this, 42);
    }
    

    您现在要做的是去掉managingClass* 参数(具体对象)但保留第二个参数int),以便用户可以决定其值调用函数时。这就是std::placeholders 的用途:

    managingClass(function<void(int)> f)
    {
        std::function<void(int)> foo =
            std::bind(&managingClass::trigger, this, std::placeholders::_1);
        // the bind is smart enough that we don't need the std::mem_fn in here
        foo(42);
        // note how we no longer need to pass the 'this' here
    }
    

    【讨论】:

      【解决方案3】:

      您对bind 的使用不正确。不使用任何占位符(_1 和类似的)的绑定表达式会产生一个没有参数的函数。如果你有一个 void foo(int)bind(&amp;foo, 20) 的类型对应于 @ 987654327@。 int 参数绑定为20,不能再从外部设置。

      这就是bind 的用途 - 绑定一些参数,并且可以选择不绑定其他参数。例如this will print 105:

      int foo(int x, int y, int z)
      { return x * y + z; }
      
      int main()
      {
        using namespace std::placeholders;
        std::function<int(int, int)> b = std::bind(&foo, _1, 10, _2);
        std::cout << b(10, 5) << '\n';
      }
      

      此外,非静态成员函数在绑定时将对象(或指向对象的指针)作为其第一个参数。因此,例如,您可以这样做this

      struct Foo
      {
        int id;
      
        int bar(int x) const
        { return 2 * x + id; }
      };
      
      int main()
      {
        using namespace std::placeholders;
        Foo foo1 = {1};
        Foo foo2 = {2};
      
        std::function<int(int)> f1 = std::bind(&Foo::bar, foo1, _1);
        std::cout << f1(10) << '\n';  // prints 21
        std::cout << f1(20) << '\n';  // prints 41
      
        std::function<int(const Foo&)> f2 = std::bind(&Foo::bar, _1, 10);
        std::cout << f2(foo1) << '\n';  // prints 21;
        std::cout << f2(foo2) << '\n';  // prints 22;
      
        std::function<int()> f3 = std::bind(&Foo::bar, foo1, 40);
        std::cout << f3() << '\n';  // prints 81;
      }
      

      我很难说出你想用你的代码实现什么,但这些信息应该足以为你指明正确的方向。

      【讨论】:

      • 非常感谢您,ComicSansMS 帮了我很多忙 :)
      猜你喜欢
      • 2016-04-02
      • 1970-01-01
      • 1970-01-01
      • 2014-03-05
      • 1970-01-01
      • 2013-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多