Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.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++ (C+;+;)新增)保存一个函数指针,以后可以调用该指针_C++_Templates_C++14 - Fatal编程技术网

C++ (C+;+;)新增)保存一个函数指针,以后可以调用该指针

C++ (C+;+;)新增)保存一个函数指针,以后可以调用该指针,c++,templates,c++14,C++,Templates,C++14,我花了一些时间想办法,但我想我需要帮助。如果我可以使用模板,我就可以避免键入函数,比如'B::theFuncToBeCalled',对吗?但是,如果我没弄错的话,只有当它是一个静态方法时,这才有效 // A.h typedef std::function <void()> CbType; class A { template<typename T> void setCallback(T &cb); private:

我花了一些时间想办法,但我想我需要帮助。如果我可以使用模板,我就可以避免键入函数,比如'B::theFuncToBeCalled',对吗?但是,如果我没弄错的话,只有当它是一个静态方法时,这才有效

// A.h
typedef std::function <void()> CbType;

class A
{
    template<typename T>
        void setCallback(T &cb);

    private:
        template <typename T>
        T callThisLater;
};

// A.cpp
template<typename T>
void A::setCallback(T &cb)
{
    this->callThisLater = cb;

    // later...

   ((CbType*)callThisLater)();
}

// B.cpp
// in constructor or wherever
{
    A* a;
    a->setCallback(this->theFuncToBeCalled);

    // or, anonymous
    CbType func = [this](){
        // do something
        // call theFuncToBeCalled() if I feel like it :)
    };

    a->setCallback(func);
}

void B::theFuncToBeCalled()
{
    log("yay");
}
//A.h
typedef std::函数CbType;
甲级
{
模板
无效设置回调(T&cb);
私人:
模板
T稍后再打电话;
};
//A.cpp
模板
void A::setCallback(T&cb)
{
this->callThisLater=cb;
//后来。。。
((CbType*)称为thislater)();
}
//B.cpp
//在构造函数中或任何地方
{
A*A;
a->setCallback(此->取消调用函数);
//或者,匿名
CbType func=[this](){
//做点什么
//如果我愿意,可以调用Functobecalled()
};
a->setCallback(func);
}
void B::theFuncToBeCalled()
{
日志(“yay”);
}

(如果我尝试以匿名方式执行此操作,则会出现访问冲突错误。)

这里有很多错误。让我们讨论一下,然后讨论如何修复它:

  • 您不能简单地在实现文件中定义模板化函数:
  • 仅对静态变量可用:
  • 变量模板定义变量族或静态数据成员

  • 您正在传递一个方法,并试图像传递函数一样使用它
  • 一旦定义了
    callThisLater
    的类型以接受方法,则随后不能将其更改为接受具有不同签名的lambda
  • 类A
    是一个很差的重新实现,它不能很好地解决函子甚至函数指针所能解决的问题
  • 请简单地消除A类,并使用函数指针和闭包类型:

    auto a = &B::theFuncToBeCalled;
    auto func = [=]() { (*this.*a)(); }
    

    我决定改变我的方法,不再使用
    a
    继续使用
    func

    而是保存一个指向成员函数所属对象的指针,而不是保存一个指向回调的指针。工作量相同,但好处是,如果我需要调用几个不同的成员函数,我可以:

    objRef->theFuncToBeCalled();
    
    // later
    objRef->theOtherFuncToBeCalled();
    

    我只需要一个指针。简单是最好的™, (对吗?:)谢谢你的帮助

    您可以只在类中保存
    std::function
    。永远不要强制转换函数。如果你得到一个类型错误,你就做错了。不要添加强制转换来使编译器静音。@xerosugar这是做错事的一个例子。如果它实际上不是
    CbType
    ,那么将其称为
    CbType
    是未定义的首先编译。您应该做的是将其声明为
    CbType callThisLater。还可以使用
    CbType
    作为
    setCallback
    的参数。不需要模板。@是的,但它们不能是非静态成员变量。