与虚拟成员函数相反,我需要一种解决方案,其中可以注册在每个级别类派生中实现的函数,以便稍后由基类调用.(不仅仅是最衍生的实现)
为此,我正在考虑为派生类提供一种机制,以便在基类中注册它们的函数,例如在派生类构造函数中.
我遇到了成员函数指针参数的问题.我以为Derived是从Base派生的,this指针应该自动生成.
这可以接近我正在尝试或我需要使用静态成员函数void *,和static_cast?
class Base
{
protected:
typedef void (Base::*PrepFn)( int n );
void registerPrepFn( PrepFn fn ) {};
}
class Derived : public Base
{
Derived() {
registerPrepFn( &Derived::derivedPrepFn );
};
void derivedPrepFn( int n ) {};
}
Run Code Online (Sandbox Code Playgroud)
编译错误:
error: no matching function for call to 'Derived::registerPrepFn(void (Derived::*)(int))'
note: candidates are: 'void Base::registerPrepFn(void (Base::*)(int))'
Run Code Online (Sandbox Code Playgroud) 我如何散列(std :: tr1 :: hash或boost :: hash)一个c ++指向成员函数的指针?
例:
我有几个bool(Class ::*functionPointer)()(不是静态的)指向类Class的几个不同的方法,我需要散列那些指向成员函数的指针.
我怎样才能做到这一点?
另外我如何比较(std :: less)那些成员函数指针,以便我可以将它们存储在std :: set中?
我试图按照Bjarne Stroustups对function模板的解释.我特别使用了c-function-pointers,functors,lambdas和member-function-pointers的可互换性
鉴于这些定义:
struct IntDiv { // functor
float operator()(int x, int y) const
{ return ((float)x)/y; }
};
// function pointer
float cfunc(int x, int y) { return (float)x+y; }
struct X { // member function
float mem(int x, int y) const { return ...; }
};
using namespace placeholders; // _1, _2, ...
Run Code Online (Sandbox Code Playgroud)
我想分配function<float(int,int)>一切可能:
int main() {
// declare function object
function<float (int x, …Run Code Online (Sandbox Code Playgroud) 如何将成员函数指针转换TIMERPROC为与WINAPI一起使用的类型SetTimer?下面的代码片段显示了我现在是如何做的,但是当我编译时,我收到此错误:
错误C2664:'SetTimer':无法将参数4从'void(__ stdcall CBuildAndSend ::*)(HWND,UINT,UINT_PTR,DWORD)'转换为'TIMERPROC'
回调需要绑定到其原始类实例.如果有更好的方法,我会全力以赴.谢谢.
class CMyClass
{
public:
void (CALLBACK CBuildAndSend::*TimerCbfn)( HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime );
private:
void CALLBACK TimeoutTimerProc( HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime );
};
CMyClass::CMyClass()
{
...
this->TimerCbfn = &CBuildAndSend::TimeoutTimerProc;
...
::CreateThread(
NULL, // no security attributes
0, // use default initial stack size
reinterpret_cast<LPTHREAD_START_ROUTINE>(BasThreadFn), // function to execute in new thread
this, // thread parameters
0, // use default creation settings
NULL // …Run Code Online (Sandbox Code Playgroud) 我一直在学习D,特别是对它的通用编程能力感到非常兴奋.代表很精彩,显然他们已经完全取代了成员函数指针,所以当我想实现类似下面的内容时,我陷入了困境:
template <typename T>
void DispatchMethodForAll(std::vector<T*> & container, void (T::* func)(void))
{
for(typename std::vector<T*>::iterator it = container.begin(); it != container.end(); ++it)
(*it)->*func();
}
Run Code Online (Sandbox Code Playgroud)
根据我在D中学到的函数指针和委托,是不是它们都不能这样做,因为函数指针只能为全局函数声明,并且委托必须绑定到一个对象,没有"部分委托" "我能找到.如此处所示,我不能使用委托,因为没有单个对象可以绑定到要调用的方法.
我知道我可以用mixins来做,并且基本上使它成为一个宏.然而,这听起来确实不像D,我认为应该有"正确的方式"
我有这个C++类,这是一个很复杂的方法compute,我想用"计算内核",一个同一类的方法.我想我会做一些事情
class test {
int classVar_ = 42;
int compute_add(int a, int b)
{
compute(int a, int b, this->add_())
}
int compute_mult(int a, int b)
{
compute(int a, int b, this->mult_())
}
int compute_(int a, int b, "pass in add or multiply as f()")
{
int c=0;
// Some complex loops {
c += f(a,b)
// }
return c;
}
int add_(int a, int b){a+b+classVar_;}
int multiply_(int a, int b){a*b+classVar_;}
...
}
Run Code Online (Sandbox Code Playgroud)
但我不确定我会怎样传递add或传递multiply.这种方法的另一种方法是传递ENUM …
将函数指针或成员函数指针带到标准函数的现有规则是什么?例如,像
auto p = &std::string::size;
Run Code Online (Sandbox Code Playgroud)
这合法吗?如果我明确地请求了正确的类型,它会或多或少是合法的,所以即使有额外的实现添加重载,它也会起作用std::string::size吗?
c++ member-function-pointers rules member-functions standard-library
我想用模板化的类包装符合'void(ClassType :: Function)(ArgType)'类型的成员函数.稍后,我想将ClassType的实例传递给此模板的实例,并让它调用包装的方法:
class Foo {
public:
Foo() : f_(0.0) {}
void set(double v) { f_ = v * 2.1; }
double get() { return f_; }
private:
double f_;
};
template <typename ArgType, typename ClassType, void (ClassType::*Method)(ArgType)>
class Wrapper {
public:
explicit Wrapper(ClassType *cls) : cls_(cls) {}
void do_something(ArgType value) {
(cls_->*Method)(value);
}
private:
ClassType *cls_;
};
#include <iostream>
int main(int argc, char ** argv) {
Foo foo;
Wrapper<double, Foo, &Foo::set> wrapper(&foo);
wrapper.do_something(1.0);
std::cout << foo.get() << std::endl;
// …Run Code Online (Sandbox Code Playgroud) c++ templates member-function-pointers template-meta-programming
(我看到之前已经问过类似的问题,但是我看到的那些问题似乎并没有完全触及我的用例.特别是,我想知道我的编译失败是否是由于一个错误,或者是我尝试什么是verboten的结果.)
我希望实现委托模式,用于事件处理.我想也许对我的需求最好的方法是成员函数指针的映射,由std :: string索引(表示事件类型.)
我开始试图完成这个std::function,但遇到了一些问题,然后决定尝试使用原始MFP.(我仍然愿意考虑std::function,我会接受一个答案,说明如何使用这种方法来完成我的确切需求.但我仍然想知道我目前的方法有什么问题.)
我能够用一个班级来完成这个工作.但是我实际上希望委托映射由抽象基类提供,然后让派生类将其委托注册到该映射中.除非我在下面的代码中犯了一些错误,否则这似乎是不可能的; 似乎成员函数指针不能是多态的.
我得到的编译错误如下:
mfp5.cpp: In constructor ‘Derived::Derived()’:
mfp5.cpp:41:21: error: cannot convert ‘int (Derived::*)(const Base::EventContext&)’ to ‘std::map<std::basic_string<char>, int (Base::*)(const Base::EventContext&)>::mapped_type {aka int (Base::*)(const Base::EventContext&)}’ in assignment
_delegates["foo"] = &Derived::FooEventHandler;
Run Code Online (Sandbox Code Playgroud)
Base::*,我想在其中插入一些Derived::*.class Base
{
public:
struct EventContext
{
int data1;
};
Base() {}
virtual int ProcessEvent(std::string event, EventContext ctx) =0;
protected:
typedef int (Base::* EventHandler)(const EventContext& context);
typedef std::map<std::string, EventHandler> EventDelegateMap;
EventDelegateMap _delegates; …Run Code Online (Sandbox Code Playgroud) 当我尝试编译以下代码时:
struct A {
void foo() & {
}
};
int main()
{
using F = void() &; // or 'typedef void F() &;'
[[maybe_unused]] F A::*pf = &A::foo;
}
Run Code Online (Sandbox Code Playgroud)
使用 clang 可以编译,但是使用 gcc 编译时会产生错误。
test.cc:9:37: error: cannot convert ‘void (A::*)() &’ to ‘void (A::*)()’ in initialization
9 | [[maybe_unused]] F A::*pf = &A::foo;
Run Code Online (Sandbox Code Playgroud)
哪种行为是正确的?