标签: member-function-pointers

解析 const 和非常量成员函数指针

在下面的代码片段中,我希望能够A::foodoWork.

但是,因为foo(const和非const)有两个重载,编译器无法解析我在调用doWork. 有没有办法告诉编译器我的意思是哪个。

我无法改变struct A

我可以在 doWork 的签名或 doWork 的调用中做一些事情来总是选择说 const 的。

我知道的一种解决方案是将函数指针类型作为参数doWork而不是模板(像这样) void doWork(void (A::*fun)(void) const){ 但这有点难看,我希望找到一个基于模板的解决方案(如果存在的话)

struct A{
    void foo() const {
    }
    void foo(){
    }
    void bar(){
    }
    void bar() const {
    }
};

template<typename F>
void doWork(F fun){
    const A a;
    (a.*fun)();
}

int main()
{
    doWork(&A::foo); //error: no matching function for call to ‘doWork()’
    doWork(&A::bar); // error: no matching …
Run Code Online (Sandbox Code Playgroud)

c++ member-function-pointers

4
推荐指数
2
解决办法
180
查看次数

指向成员函数的函数

我想使用一个库(nlopt),它有一个函数set_min_objective,它接受一个指向数值函数myfunc的指针并找到它的最小值.我想创建一个包含适当初始化成员函数的类.然后set_min_objective将在特定实例中找到最佳值(下例中的myP).呼叫顺序是:

opt.set_min_objective(myfunc, NULL);
Run Code Online (Sandbox Code Playgroud)

我想使用类似的东西:

opt.set_min_objective(myP.f, NULL);
Run Code Online (Sandbox Code Playgroud)

编译时得到的错误是:

main.cpp: In function 'int main()':
main.cpp:79:34: error: no matching function for call to 'nlopt::opt::set_min_objective(<unresolved overloaded function type>, NULL)'
../lib/nlopt.hpp:335:10: note: candidates are: void nlopt::opt::set_min_objective(double (*)(unsigned int, const double*, double*, void*), void*)
../lib/nlopt.hpp:342:10: note:                 void nlopt::opt::set_min_objective(double (*)(const std::vector<double>&, std::vector<double>&, void*), void*)
../lib/nlopt.hpp:368:10: note:                 void nlopt::opt::set_min_objective(double (*)(unsigned int, const double*, double*, void*), void*, void* (*)(void*), void* (*)(void*))
Run Code Online (Sandbox Code Playgroud)

set_min_objective接受myP.f作为函数的普通指针最简单的解决方案是什么?请注意,myP.f和myfunc具有相同的参数和返回值类型.

谢谢,

JD

c++ member-function-pointers function-pointers nlopt

3
推荐指数
1
解决办法
950
查看次数

如何在STL容器和成员函数调用中存储模板化对象

假设你有一个类

template<class T>
struct A {
  void foo() {
    // Need access to "T" here
    typedef typename someTrait<T>::someType T2;
  }
};
Run Code Online (Sandbox Code Playgroud)

并且您希望用容器(可能是STL)"注册"(或存储)该类的实例(或指向它的指针),以便稍后调用foo()所有已注册实例的方法.

由于要实例化用不同模板参数实例化的实例(A<int>,A<float>...)显然不能使用a std::vector并将实例或指针存储到它.我能想象的是制作方法static和存储函数指针void foo(),如:

 void static foo();

 typedef void (* fooPtr)(void);
 std::vector<fooPtr>
Run Code Online (Sandbox Code Playgroud)

但不知怎的,我觉得这不是很C++ 11-ish.是否有一个很好的解决方案,它引入了一个包装类或什么?

引入基类并使用动态转换会引入依赖关系RTTI,对吧?我想避免依赖RTTI.

如何在C++ 11中做到这一点?(我不想引入额外的依赖关系,如链接到Boost或依赖RTTI.)

谢谢你的意见!

c++ templates stl member-function-pointers c++11

3
推荐指数
2
解决办法
613
查看次数

在C++中使用超时处理程序实现计时器

我需要在c ++中实现带有超时处理函数的计时器.对于这个我创建一个定时器,我初始化sigev_notify_function的sigevent与类的成员函数中的一个.下面是代码.

timer.hpp

#ifndef TIMERHELPER_H_
#define TIMERHELPER_H_

#include <signal.h>
#include <time.h>
#include <pthread.h>
#include <iostream>

using namespace std;

#define CLOCKID CLOCK_REALTIME
#define SIG SIGUSR1

typedef void (*TimerHandler)(sigval_t signum);

class TimerTimeoutHandler
{
    public:
        virtual void handlerFunction( void ) = 0;
};

class Timer
{
    public:
        Timer( TimerTimeoutHandler * timeHandler );
        ~Timer();

        void setDuration(long int seconds);
        void start();
        void restart();
        void timeout();
        void stop();

    private:
        void createTimer(timer_t *timerid, TimerHandler handler_cb);
        void startTimer(timer_t timerid, int startTimeout, int cyclicTimeout);
        void …
Run Code Online (Sandbox Code Playgroud)

c++ member-function-pointers

3
推荐指数
1
解决办法
7672
查看次数

类方法错误的指针数组c ++ 11

我得到一个小的"问题"与类方法的指针数组.

简而言之:我的班级综合体有四个功能 - double funX(void):

double fun1(void) const {...}
double fun2(void) const {...}
...
Run Code Online (Sandbox Code Playgroud)

然后我有一些指向上述配方的成员函数的指针.

double (Complex::*arr_ptr_fun[4])(void) const;
Run Code Online (Sandbox Code Playgroud)

我在构造函数初始化列表中初始化此数组:

... : re(_re), im(_im), arr_ptr_fun{&fun1,&fun2,&fun3,&fun4} { /*EMPTY*/ }
Run Code Online (Sandbox Code Playgroud)

当我尝试通过这个数组调用这4个函数中的任何一个时,例如:

std::cout << this->*arr_ptr_fun[0]();
Run Code Online (Sandbox Code Playgroud)

我收到一个我不明白的错误:

error: must use '.*' or '->*' to call pointer-to-member function in '((const Complex*)this)->Complex::arr_ptr_fun[0] (...)', e.g. '(... ->* ((const Complex*)this)->Complex::arr_ptr_fun[0]) (...)'
     double fun4(void) const {std::cout << this->*arr_ptr_fun[0](); return sqrt(fun3());}
Run Code Online (Sandbox Code Playgroud)

使用.*->*通过哪个指针...?(chaos *宇宙指针?)

有任何想法吗?

c++ member-function-pointers

3
推荐指数
2
解决办法
237
查看次数

为什么gcc和clang会为成员函数模板参数生成非常不同的代码?

我试图了解当成员函数指针用作模板参数时发生了什么.我一直认为函数指针(或成员函数指针)是一个运行时概念,所以我想知道当它们被用作模板参数时会发生什么.出于这个原因,我看了一下这段代码产生的输出:

struct Foo { void foo(int i){ } };    
template <typename T,void (T::*F)(int)>
void callFunc(T& t){ (t.*F)(1); }
void callF(Foo& f){ f.foo(1);}    
int main(){
    Foo f;
    callF(f);
    callFunc<Foo,&Foo::foo>(f);
}
Run Code Online (Sandbox Code Playgroud)

在哪里callF比较.gcc 6.2为两个函数生成完全相同的输出:

callF(Foo&):  // void callFunc<Foo, &Foo::foo>(Foo&):
    push    rbp
    mov     rbp, rsp
    sub     rsp, 16
    mov     QWORD PTR [rbp-8], rdi
    mov     rax, QWORD PTR [rbp-8]
    mov     esi, 1
    mov     rdi, rax
    call    Foo::foo(int)
    nop
    leave
    ret
Run Code Online (Sandbox Code Playgroud)

同时clang 3.9 产生几乎相同的输出callF():

callF(Foo&):                          # @callF(Foo&)
    push    rbp …
Run Code Online (Sandbox Code Playgroud)

c++ gcc templates member-function-pointers clang

3
推荐指数
1
解决办法
96
查看次数

制作常规函数用模板包装成员函数

我正在使用一个具有C API的框架,其中typedef看起来像这样:

typedef int (*function_type)(int argc, voidptr_t args[], void *data)
Run Code Online (Sandbox Code Playgroud)

以及一个函数,它接受如下所示的函数指针:

void create_callback(function_type fn, void *data);
Run Code Online (Sandbox Code Playgroud)

(如果不明显,voidptr_t只是void*的另一个typedef)

框架将根据需要在特定时间调用回调,并设置argc和args参数以反映当时有效的条件.argc将永远不会小于1,并且args中的第一个条目将始终是指向某些有效数据的指针,这些数据可以转换为指向程序中某个类的指针,并且可以在很多方面被认为是"this"指针,因为它指示回调应该作用或使用的对象或数据.

我将从C++调用此API,并且想要一种方法来包装类似于以下的类的成员函数:

class A
{
    int member_fn1(int argc, voidptr_t args[], void *data);
};

class B
{
    int member_fn2(int argc, voidptr_t args[], void *data);
};
Run Code Online (Sandbox Code Playgroud)

现在我想要一种方法来使用这些成员函数作为回调....我可以通过更改A和B的定义来包含我可以用作回调的静态函数,如下所示:

class A
{
    int member_fn1(int argc, voidptr_t args[], void *data);
    static int call_fn1(int argc, voidptr_t args[], void *data)
    {
       ((A*)args[0])->*fn1(argc-1,&args[1],dat
    }
};

class B
{
    int member_fn2(int argc, voidptr_t args[], void *data);
    static int call_fn2(int argc, …
Run Code Online (Sandbox Code Playgroud)

c++ templates member-function-pointers c++11

3
推荐指数
1
解决办法
166
查看次数

在结构外部调用指向函数的指针

我有一个结构,里面是一个指向同一结构的函数的指针.现在我需要调用一个指向结构外部函数的指针.我举一个下面的代码示例:

#include <iostream>

struct test {
    void (test::*tp)(); // I need to call this pointer-to-function
    void t() {
        std::cout << "test\n";
    }
    void init() {
        tp = &test::t;
    }
    void print() {
        (this->*tp)();
    }
};
void (test::*tp)();

int main() {
    test t;
    t.init();
    t.print();
    (t.*tp)(); // segfault, I need to call it
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ member-function-pointers

3
推荐指数
1
解决办法
53
查看次数

我可以合法地将成员函数指针转换为函数指针吗?

我继承了一些C ++代码,并且承担了摆脱警告的任务。

在这里,我们有一个成员函数指针被转换为一个函数指针。我知道成员函数指针与函数指针“不同”,因为在内部有一个隐含的“ this”参数。但是,我的前任似乎已经明确地利用了这一事实,即从成员函数指针转换为插入了附加第一个参数的函数指针。

我的问题是:

A)我可以摆脱编译器警告吗?

B)该代码在什么程度上可以保证工作?

为了这个问题,我将其缩减为一个小的main.cpp:

#define GENERIC_FUNC_TYPE   void(*)(void)
#define FUNC_TYPE       int(*)(void *)

class MyClass
{
public:
    MyClass(int a) : memberA(a) {}
    int myMemberFunc()
    {
        return memberA;
    }

private:
    int memberA;
};

int main(int argc, char*argv[])
{
    int (MyClass::* memberFunc) () = &MyClass::myMemberFunc;
    MyClass myObject(1);
    std::cout << (myObject.*memberFunc)() << std::endl;
    // All good so far

    // Now get naughty, store it away in a very basic fn ptr
    void(*myStoredFunction)(void) = (GENERIC_FUNC_TYPE)memberFunc;  // Compiler warning

    // Reinterpret the fn …
Run Code Online (Sandbox Code Playgroud)

c++ member-function-pointers

3
推荐指数
1
解决办法
132
查看次数

C ++-将对象(如字符串)映射到表中的成员函数的正确方法

我正在处理由第三方API定义的事件。这些事件由字符串标识符标识,即"EventABC"

我需要将表中的这些(字符串)事件映射到对象的成员函数。

最安全,最干净的方法是什么?

c++ member-function-pointers function-pointers functor c++11

3
推荐指数
1
解决办法
83
查看次数