在下面的代码片段中,我希望能够A::foo从doWork.
但是,因为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) 我想使用一个库(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
假设你有一个类
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 ++中实现带有超时处理函数的计时器.对于这个我创建一个定时器,我初始化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) 我得到一个小的"问题"与类方法的指针数组.
简而言之:我的班级综合体有四个功能 - 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 *宇宙指针?)
有任何想法吗?
我试图了解当成员函数指针用作模板参数时发生了什么.我一直认为函数指针(或成员函数指针)是一个运行时概念,所以我想知道当它们被用作模板参数时会发生什么.出于这个原因,我看了一下这段代码产生的输出:
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 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) 我有一个结构,里面是一个指向同一结构的函数的指针.现在我需要调用一个指向结构外部函数的指针.我举一个下面的代码示例:
#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 ++代码,并且承担了摆脱警告的任务。
在这里,我们有一个成员函数指针被转换为一个函数指针。我知道成员函数指针与函数指针“不同”,因为在内部有一个隐含的“ 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) 我正在处理由第三方API定义的事件。这些事件由字符串标识符标识,即"EventABC"
我需要将表中的这些(字符串)事件映射到对象的成员函数。
题
最安全,最干净的方法是什么?
c++ member-function-pointers function-pointers functor c++11