实现功能对象绑定而无需使用C 11

implement function object bind without using c++11

本文关键字:功能 对象 绑定 实现      更新时间:2023-10-16

我正在尝试实现自己的函数对象类和绑定功能(只需要包含2个参数的成员函数(。我仅限于使用GCC 4.4.6,而C 0x不是一个选项。

我的代码如下。它不会编译。

#pragma once
namespace utils
{
template<class>
class CFunction;
template<class TRet, class Arg1, class Arg2>
class CFunction<TRet(Arg1, Arg2)>
{
public:
    typedef TRet (*FuncPtr) (void*, Arg1, Arg2);
    void* m_pObj;
    FuncPtr m_FuncPtr;
    TRet operator()(Arg1 arg1, Arg2 arg2)
    {
        return m_FuncPtr(arg1, arg2);
    }
    template <class TObj, TRet (TObj::*TMemFunc)(Arg1, Arg2)>
    static CFunction Create(TObj* pObj)
    {
        CFunction Ret;
        Ret.m_pObj = (void*)pObj;
        Ret.m_FuncPtr = &Caller<TObj, TMemFunc>;
        return Ret;
    }
private:
    template<class TObj, TRet (TObj::*TMemFunc)(Arg1, Arg2)>
    static TRet Caller(void* obj, Arg1 arg1, Arg2 arg2)
    {
        TObj* pObj = static_cast<TObj*>(obj);
        return (pObj->*TMemFunc)(arg1, arg2);
    }
};

template<class TRet, class TClass, class Arg1, class Arg2>
CFunction<TRet(Arg1, Arg2)> Bind(TRet (TClass::*func)(Arg1, Arg2), TClass *pObj)
{
    return CFunction<TRet(Arg1, Arg2)>::Create<TClass, func>();
}
} // end of namespace utils

编译报告

Functional.h: In function ‘utils::CFunction<TRet(Arg1, Arg2)> utils::Bind(TRet (TClass::*)(Arg1, Arg2), TClass*)’:
Functional.h:48: error: expected primary-expression before ‘,’ token
Functional.h:48: error: expected primary-expression before ‘)’ token

任何人会告诉我代码有什么问题以及如何使其起作用


解决了问题@vittorio和@msalters。我有新的编译错误。

修复代码

#include <iostream>
namespace utils
{
template<class>
class CFunction;
template<class TRet, class Arg1, class Arg2>
class CFunction<TRet(Arg1, Arg2)>
{
public:
    typedef TRet (*FuncPtr) (void*, Arg1, Arg2);
    void* m_pObj;
    FuncPtr m_FuncPtr;
    TRet operator()(Arg1 arg1, Arg2 arg2)
    {
        return m_FuncPtr(m_pObj, arg1, arg2);
    }
    template <class TObj, TRet (TObj::*TMemFunc)(Arg1, Arg2)>
    static CFunction Create(TObj* pObj)
    {
        CFunction Ret;
        Ret.m_pObj = (void*)pObj;
        Ret.m_FuncPtr = &Caller<TObj, TMemFunc>;
        return Ret;
    }
private:
    template<class TObj, TRet (TObj::*TMemFunc)(Arg1, Arg2)>
    static TRet Caller(void* obj, Arg1 arg1, Arg2 arg2)
    {
        TObj* pObj = static_cast<TObj*>(obj);
        return (pObj->*TMemFunc)(arg1, arg2);
    }
};

template<class TRet, class TClass, class Arg1, class Arg2>
CFunction<TRet(Arg1, Arg2)> Bind(TRet (TClass::*func)(Arg1, Arg2), TClass *pObj)
{
    return CFunction<TRet(Arg1, Arg2)>::template Create<TClass, func>(pObj);
}
} // end of namespace utils
class TestLogic
{
public:
  bool Test(std::string& str, double d) {
     std::cout << str << ",  " << d << std::endl;
     return true;
  }
};
int main(int argc, const char **argv) {
    TestLogic testObj;
    utils::CFunction<bool(std::string&, double)> f = utils::Bind(&TestLogic::Test, &testObj);
    std::string str("hello");
    f(str, -1.0);
}

新错误:

prog.cc: In function 'utils::CFunction<TRet(Arg1, Arg2)> utils::Bind(TRet (TClass::*)(Arg1, Arg2), TClass*) [with TRet = bool, TClass = TestLogic, Arg1 = std::string&, Arg2 = double]':
prog.cc:59:   instantiated from here
prog.cc:43: error: 'func' is not a valid template argument for type 'bool (TestLogic::*)(std::string&, double)'
prog.cc:43: error: it must be a pointer-to-member of the form `&X::Y'
prog.cc:43: error: no matching function for call to 'utils::CFunction<bool(std::string&, double)>::Create(TestLogic*&)'

有人可以帮助我吗?

您可以运行此代码输入链接说明

您需要使用template关键字作为Bind中的DiSambiguator:

return CFunction<TRet(Arg1, Arg2)>::template Create<TClass, func>();
//                                  ^~~~~~~~

这是因为Create是一个因名称,并且编译器不知道您是否试图调用模板函数或将其与TClass进行比较。有关该主题的更多阅读:在哪里以及为什么要放置"模板"。和" typename"关键字?