Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ ';不匹配';使用std::tr1::function的成员回调函数出错_C++_Function_Tr1 - Fatal编程技术网

C++ ';不匹配';使用std::tr1::function的成员回调函数出错

C++ ';不匹配';使用std::tr1::function的成员回调函数出错,c++,function,tr1,C++,Function,Tr1,我正在尝试使用指向公共成员函数的str::tr1::function创建回调函数 std::tr1::function < int (const string& , const MessageInfo* , const void* , const int , const void* ) > dssCallBack; dssCallBack = &ABC::mDBtoDScallback; 当我试图编译它时,我从g++中得到以下错误 In file included

我正在尝试使用指向公共成员函数的str::tr1::function创建回调函数

std::tr1::function < int (const string& , const MessageInfo* , const void* , const int , const void* ) > dssCallBack;
dssCallBack = &ABC::mDBtoDScallback;
当我试图编译它时,我从g++中得到以下错误

In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/tr1/functional:56,
                 from ../src/bmrk/databus/ABC.hpp:17,
                 from ../src/bmrk/databus/ABC.cpp:1:
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/tr1_impl/functional: In static member function ‘static _Res std::tr1::_Function_handler<_Res(_ArgTypes ...), _Member _Class::*>::_M_invoke(const std::tr1::_Any_data&, _ArgTypes ...) [with _Class = ABC, _Member = int(const std::string&, const MessageInfo*, const void*, int, const void*), _Res = int, _ArgTypes = const std::string&, const MessageInfo*, const void*, int, const void*]’:
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/tr1_impl/functional:2005:   instantiated from ‘std::tr1::function<_Res(_ArgTypes ...)>::function(_Functor, typename __gnu_cxx::__enable_if<(! std::tr1::is_integral::value), std::tr1::function<_Res(_ArgTypes ...)>::_Useless>::__type) [with _Functor = int (ABC::*)(const std::string&, const MessageInfo*, const void*, int, const void*), _Res = int, _ArgTypes = const std::string&, const MessageInfo*, const void*, int, const void*]’

/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/tr1_impl/functional:1885:   instantiated from ‘typename __gnu_cxx::__enable_if<(! std::tr1::is_integral::value), std::tr1::function<_Res(_ArgTypes ...)>&>::__type std::tr1::function<_Res(_ArgTypes ...)>::operator=(_Functor) [with _Functor = int (ABC::*)(const std::string&, const MessageInfo*, const void*, int, const void*), _Res = int, _ArgTypes = const std::string&, const MessageInfo*, const void*, int, const void*]’
../src/bmrk/databus/dataservice_subscriber.cpp:266:   instantiated from here

/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/tr1_impl/functional:1714: error: no match for call to ‘(std::tr1::_Mem_fn<int (ABC::*)(const std::string&, const MessageInfo*, const void*, int, const void*)>) (const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const MessageInfo*&, const void*&, int&, const void*&)’

/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/tr1_impl/functional:546: note: candidates are: _Res std::tr1::_Mem_fn<_Res (_Class::*)(_ArgTypes ...)>::operator()(_Class&, _ArgTypes ...) const [with _Res = int, _Class = ABC, _ArgTypes = const std::string&, const MessageInfo*, const void*, int, const void*]

/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/tr1_impl/functional:551: note:                 _Res std::tr1::_Mem_fn<_Res (_Class::*)(_ArgTypes ...)>::operator()(_Class*, _ArgTypes ...) const [with _Res = int, _Class = ABC, _ArgTypes = const std::string&, const MessageInfo*, const void*, int, const void*]
我尝试了注释和未注释选项,但现在出现了这个错误

In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/tr1/functional:56,
                 from ../src/bmrk/databus/ABC.hpp:17,
                 from ../src/bmrk/databus/ABC.cpp:1:
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/tr1_impl/functional: In member function ‘typename std::tr1::result_of<_Functor(typename std::tr1::result_of<std::tr1::_Mu<_Bound_args, std::tr1::is_bind_expression::value, (std::tr1::is_placeholder::value > 0)>(_Bound_args, std::tr1::tuple<_UElements ...>)>::type ...)>::type std::tr1::_Bind<_Functor(_Bound_args ...)>::__call(const std::tr1::tuple<_UElements ...>&, std::tr1::_Index_tuple<_Indexes ...>) [with _Args = const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const MessageInfo*&, const void*&, int&, const void*&, int ..._Indexes = 0, _Functor = std::tr1::_Mem_fn<int (ABC::*)(const std::string&, const MessageInfo*, const void*, int, const void*)>, _Bound_args = ABC*]’:
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/tr1_impl/functional:1191:   instantiated from ‘typename std::tr1::result_of<_Functor(typename std::tr1::result_of<std::tr1::_Mu<_Bound_args, std::tr1::is_bind_expression::value, (std::tr1::is_placeholder::value > 0)>(_Bound_args, std::tr1::tuple<_UElements ...>)>::type ...)>::type std::tr1::_Bind<_Functor(_Bound_args ...)>::operator()(_Args& ...) [with _Args = const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, const MessageInfo*, const void*, int, const void*, _Functor = std::tr1::_Mem_fn<int (ABC::*)(const std::string&, const MessageInfo*, const void*, int, const void*)>, _Bound_args = ABC*]’
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/tr1_impl/functional:1654:   instantiated from ‘static _Res std::tr1::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_invoke(const std::tr1::_Any_data&, _ArgTypes ...) [with _Res = int, _Functor = std::tr1::_Bind<std::tr1::_Mem_fn<int (ABC::*)(const std::string&, const MessageInfo*, const void*, int, const void*)>(ABC*)>, _ArgTypes = const std::string&, const MessageInfo*, const void*, int, const void*]’
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/tr1_impl/functional:2005:   instantiated from ‘std::tr1::function<_Res(_ArgTypes ...)>::function(_Functor, typename __gnu_cxx::__enable_if<(! std::tr1::is_integral::value), std::tr1::function<_Res(_ArgTypes ...)>::_Useless>::__type) [with _Functor = std::tr1::_Bind<std::tr1::_Mem_fn<int (ABC::*)(const std::string&, const MessageInfo*, const void*, int, const void*)>(ABC*)>, _Res = int, _ArgTypes = const std::string&, const MessageInfo*, const void*, int, const void*]’
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/tr1_impl/functional:1885:   instantiated from ‘typename __gnu_cxx::__enable_if<(! std::tr1::is_integral::value), std::tr1::function<_Res(_ArgTypes ...)>&>::__type std::tr1::function<_Res(_ArgTypes ...)>::operator=(_Functor) [with _Functor = std::tr1::_Bind<std::tr1::_Mem_fn<int (ABC::*)(const std::string&, const MessageInfo*, const void*, int, const void*)>(ABC*)>, _Res = int, _ArgTypes = const std::string&, const MessageInfo*, const void*, int, const void*]’
../src/bmrk/databus/ABC.cpp:266:   instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/tr1_impl/functional:1137: error: no match for call to ‘(std::tr1::_Mem_fn<int (ABC::*)(const std::string&, const MessageInfo*, const void*, int, const void*)>) (ABC*&)’
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/tr1_impl/functional:546: note: candidates are: _Res std::tr1::_Mem_fn<_Res (_Class::*)(_ArgTypes ...)>::operator()(_Class&, _ArgTypes ...) const [with _Res = int, _Class = ABC, _ArgTypes = const std::string&, const MessageInfo*, const void*, int, const void*]
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/tr1_impl/functional:551: note:                 _Res std::tr1::_Mem_fn<_Res (_Class::*)(_ArgTypes ...)>::operator()(_Class*, _ArgTypes ...) const [with _Res = int, _Class = ABC, _ArgTypes = const std::string&, const MessageInfo*, const void*, int, const void*]
make[1]: *** [ABC.lo] Error 1

谢谢。

如评论中所述,问题似乎是因为您的函数对象需要一个静态的非对象绑定函数,而您实际上是在向它传递一个成员。从我所看到的,有几个解决办法,最简单的一个你可能已经在考虑;使用静态指针并将对象的指针作为参数传递

或者,我不知道这是否适用于您的特定体系结构,但下面是如何使用
std::mem\u fn
结合
std::function
调用具有指定对象的成员函数的简要介绍。这是一个独立的样本,但我希望你能看到它如何帮助你

#include <iostream>
#include <functional>
using namespace std;

class MyClass
{
public:
    MyClass() {}

    int CallMe(void *p, int a, float f)
    {
        // use params herere
        cout << "CallMe fired : " << this << " !\n" << endl;
        return 0;
    }
};

int main()
{
    MyClass obj, obj2;
    std::function<int(MyClass*,void*,int,float)> fn(std::mem_fn(&MyClass::CallMe));

    cout << "Invoking CallMe with " << &obj << " object..." << endl;
    fn(&obj, NULL, 1, 2.0);

    cout << "Invoking CallMe with " << &obj2 << " object..." << endl;
    fn(&obj2, NULL, 1, 2.0);

    return 0;
}
注意

我对C++11中提供的有关成员函数对象如何工作的阅读非常感兴趣。并不是说有人真的关心这个。我不知道他们是否正确地发送给虚拟人等等,但我对他们绝对感到惊讶

我希望您会觉得这很有帮助,但如果一位真正了解std::function、std::bind和std::men的深度的std lib专家提供了更简洁的解释(或将此片段撕成碎片),我完全准备删除它。老实说,通过
std::function
调用成员可能有更好的示例,但是我不得不说,将
std::men
std::function
一起使用非常简单


虚拟调度

在征求了DeadMG的意见后,我真的很好奇虚拟调度是否有效。我认为这是一个很好的机会,因为我们提供了一个
this
指针,但我并没有屏住呼吸,因为很明显我们通过地址将
MyClass::CallMe
成员传递给了
std:::mem\u fn
的构造函数

更新的源代码和结果运行非常有趣。请注意,两个实例中使用的函数对象相同。我不能说它是否打算以这种方式工作(顺便说一句,似乎是这样),但它对我来说还是很有趣的

#include <iostream>
#include <functional>
using namespace std;

class MyClass
{
public:
    MyClass() {}

    virtual int CallMe(void *p, int a, float f)
    {
        // use params herere
        cout << "MyClass::CallMe fired : " << this << endl;
        return 0;
    }
};

class MyDerived : public MyClass
{
public:
    MyDerived() {}

    virtual int CallMe(void *p, int a, float f)
    {
        // use params herere
        cout << "MyDerived::CallMe fired : " << this << endl;
        return 0;
    }
};

int main()
{
    MyClass obj;
    MyDerived obj2;

    std::function<int(MyClass*,void*,int,float)> fn(std::mem_fn(&MyClass::CallMe));

    cout << "Invoking CallMe with " << &obj << " object..." << endl;
    fn(&obj, NULL, 1, 2.0);

    cout << "Invoking CallMe with " << &obj2 << " object..." << endl;
    fn(&obj2, NULL, 1, 2.0);

    return 0;
}

正如在注释中所讨论的,这个问题似乎是因为您的函数对象需要一个静态的非对象绑定函数,而实际上您正在向它传递一个成员。从我所看到的,有几个解决办法,最简单的一个你可能已经在考虑;使用静态指针并将对象的指针作为参数传递

或者,我不知道这是否适用于您的特定体系结构,但下面是如何使用
std::mem\u fn
结合
std::function
调用具有指定对象的成员函数的简要介绍。这是一个独立的样本,但我希望你能看到它如何帮助你

#include <iostream>
#include <functional>
using namespace std;

class MyClass
{
public:
    MyClass() {}

    int CallMe(void *p, int a, float f)
    {
        // use params herere
        cout << "CallMe fired : " << this << " !\n" << endl;
        return 0;
    }
};

int main()
{
    MyClass obj, obj2;
    std::function<int(MyClass*,void*,int,float)> fn(std::mem_fn(&MyClass::CallMe));

    cout << "Invoking CallMe with " << &obj << " object..." << endl;
    fn(&obj, NULL, 1, 2.0);

    cout << "Invoking CallMe with " << &obj2 << " object..." << endl;
    fn(&obj2, NULL, 1, 2.0);

    return 0;
}
注意

我对C++11中提供的有关成员函数对象如何工作的阅读非常感兴趣。并不是说有人真的关心这个。我不知道他们是否正确地发送给虚拟人等等,但我对他们绝对感到惊讶

我希望您会觉得这很有帮助,但如果一位真正了解std::function、std::bind和std::men的深度的std lib专家提供了更简洁的解释(或将此片段撕成碎片),我完全准备删除它。老实说,通过
std::function
调用成员可能有更好的示例,但是我不得不说,将
std::men
std::function
一起使用非常简单


虚拟调度

在征求了DeadMG的意见后,我真的很好奇虚拟调度是否有效。我认为这是一个很好的机会,因为我们提供了一个
this
指针,但我并没有屏住呼吸,因为很明显我们通过地址将
MyClass::CallMe
成员传递给了
std:::mem\u fn
的构造函数

更新的源代码和结果运行非常有趣。请注意,两个实例中使用的函数对象相同。我不能说它是否打算以这种方式工作(顺便说一句,似乎是这样),但它对我来说还是很有趣的

#include <iostream>
#include <functional>
using namespace std;

class MyClass
{
public:
    MyClass() {}

    virtual int CallMe(void *p, int a, float f)
    {
        // use params herere
        cout << "MyClass::CallMe fired : " << this << endl;
        return 0;
    }
};

class MyDerived : public MyClass
{
public:
    MyDerived() {}

    virtual int CallMe(void *p, int a, float f)
    {
        // use params herere
        cout << "MyDerived::CallMe fired : " << this << endl;
        return 0;
    }
};

int main()
{
    MyClass obj;
    MyDerived obj2;

    std::function<int(MyClass*,void*,int,float)> fn(std::mem_fn(&MyClass::CallMe));

    cout << "Invoking CallMe with " << &obj << " object..." << endl;
    fn(&obj, NULL, 1, 2.0);

    cout << "Invoking CallMe with " << &obj2 << " object..." << endl;
    fn(&obj2, NULL, 1, 2.0);

    return 0;
}

来源很简单,如果你知道去哪里找的话。考虑下面的代码:

std::tr1::function < int (const string& , const MessageInfo* , const void* , const int , const void* ) > dssCallBack;
dssCallBack = &ABC::mDBtoDScallback;
dssCallBack(std::string(), nullptr, nullptr, 0, nullptr);
std::tr1::functiondss回调;
dssCallBack=&ABC::mDBtoDScallback;
dssCallBack(std::string(),nullptr,nullptr,0,nullptr);
这是什么?你从来没有提供过。因此,
std::function
不可能实现这一点-您试图调用一个成员,但没有提供对象。
std::function
应该做什么,神奇地决定这个
应该是什么


这两种解决方案是,使用
std::bind
绑定
this
,或者将
this
作为参数传递,如
std::mem\fn
如果您知道在哪里查找,那么源代码很简单。考虑下面的代码:

std::tr1::function < int (const string& , const MessageInfo* , const void* , const int , const void* ) > dssCallBack;
dssCallBack = &ABC::mDBtoDScallback;
dssCallBack(std::string(), nullptr, nullptr, 0, nullptr);
std::tr1::functiondss回调;
dssCallBack=&ABC::mDBtoDScallback;
dssCallBack(std::string(),nullptr,nullptr,0,nullptr);
这是什么?你从来没有提供过。因此,
std::function
不可能实现这一点-您试图调用一个成员,但没有提供对象。
std::function
应该做什么,神奇地决定这个
应该是什么

这两种解决方案是,使用
std::bindthis
Invoking CallMe with 0x7fff5fbff7d8 object...
CallMe fired : 0x7fff5fbff7d8 !

Invoking CallMe with 0x7fff5fbff7d0 object...
CallMe fired : 0x7fff5fbff7d0 !
#include <iostream>
#include <functional>
using namespace std;

class MyClass
{
public:
    MyClass() {}

    virtual int CallMe(void *p, int a, float f)
    {
        // use params herere
        cout << "MyClass::CallMe fired : " << this << endl;
        return 0;
    }
};

class MyDerived : public MyClass
{
public:
    MyDerived() {}

    virtual int CallMe(void *p, int a, float f)
    {
        // use params herere
        cout << "MyDerived::CallMe fired : " << this << endl;
        return 0;
    }
};

int main()
{
    MyClass obj;
    MyDerived obj2;

    std::function<int(MyClass*,void*,int,float)> fn(std::mem_fn(&MyClass::CallMe));

    cout << "Invoking CallMe with " << &obj << " object..." << endl;
    fn(&obj, NULL, 1, 2.0);

    cout << "Invoking CallMe with " << &obj2 << " object..." << endl;
    fn(&obj2, NULL, 1, 2.0);

    return 0;
}
Invoking CallMe with 000000000021FB58 object...
MyClass::CallMe fired : 000000000021FB58
Invoking CallMe with 000000000021FB78 object...
MyDerived::CallMe fired : 000000000021FB78
std::tr1::function < int (const string& , const MessageInfo* , const void* , const int , const void* ) > dssCallBack;
dssCallBack = &ABC::mDBtoDScallback;
dssCallBack(std::string(), nullptr, nullptr, 0, nullptr);