在不使用c ++ 11的情况下实现函数对象绑定

时间:2019-05-16 12:13:31

标签: c++ function templates

我正在尝试实现自己的函数对象类和绑定函数(只需要包装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*&)'

有人可以帮助我吗?

您可以运行此代码enter link description here

1 个答案:

答案 0 :(得分:3)

您需要在<template>中将v-for用作歧义词:

created: function(){
    $('#scroll_horizontal_table').DataTable(); // THIS IS THE PROBLEM, HOW AND WHERE TO PUT?

    this.userData(),
    db.ref("chatmodel")
    .once("value")
    .then(dataSnapshot => {
      const itemsArray = [];
      dataSnapshot.forEach(childSnapshot => {
        const childData = childSnapshot.val();
        itemsArray.push({
          fotografijaKorisnik: childData.userModel.photo_profile,
          imeKorisnik: childData.userModel.name,
          telefonKorisnik: childData.userModel.phoneNumber,
          emailKorisnik: childData.userModel.email,
          datumPoruka: childData.timeStamp,
          sadrzajPoruka: childData.message,
          datotekaPoruka: childData.fileModel.name_file,
          datotekaPorukaURL: childData.fileModel.url_file,
          kartaLat: childData.mapModel.latitude,
          kartaLong: childData.mapModel.longitude
        });
      });
      this.chatItems = itemsArray; // reverse()
    });
},
...

这是因为template是从属名称,并且编译器不知道您是要调用模板函数还是将其与Bind进行比较。有关该主题的更多阅读内容:Where and why do I have to put the "template" and "typename" keywords?