鉴于以下代码,我无法编译.
template < typename OT, typename KT, KT (OT::* KM)() const >
class X
{
public:
KT mfn( const OT & obj )
{
return obj.*(KM)(); // Error here.
}
};
class O
{
public:
int func() const
{
return 3;
}
};
int main( int c, char *v[] )
{
int a = 100;
X< O, int, &O::func > x;
O o;
std::cout << x.mfn( o ) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我收到了folling错误消息
error: must use '.*' or '->*' to call …Run Code Online (Sandbox Code Playgroud) c++ templates member-function-pointers function-pointers pointer-to-member
我一直在讨论与前一个问题相关的成员函数指针.在下面的代码中,我调用类(B)上的方法来更改其中的变量(count),但我从不创建此类的实例.为什么这样做?
#include <iostream>
#include <string>
#include <map>
class A;
typedef int (A::*MEMFUNC)(int, int);
#define HANDLER(aclass, aproc) (MEMFUNC)(&aclass::aproc)
enum
{
ADD=1,
MUL,
SUB,
DIV
};
class B
{
int count;
public:
B() : count(0) {}
~B() {}
int multiply(int x, int y) { count++; return x*y*count; }
int divide(int x, int y) { count++; if (y!=0) return (x/y)*count; else return 0; }
};
class A
{
std::map< int, MEMFUNC > funcs;
public:
A() { AddLocals(); }
~A() {}
int …Run Code Online (Sandbox Code Playgroud) 好吧,我再一次打砖了.再一次,我没有看到它是错误的原因,不知道如何让它工作:
我有一个类Human的实例.Human类派生自Object .. Object类有一个名为"PerformStep"的vitrual函数.在人类类重载这个函数.
人类也有"WalkAction"功能.现在我想在PerformStep - By成员函数指针期间调用这个"walkaction".
我喜欢用指针做这个:
人类是愚蠢的:他们知道如何走路,但不知道何时走路.所以在这一步中会问一个神实例:"我现在该怎么做" - 然后那个神实例返回指向正确成员函数的指针.
virtual void PerformStep()
{
postion.x += 0; //redundant line to check for the debugger
CALL_MEMBER_FN(*this,&Human::WalkAction);
Object::PerformStep();
}
Run Code Online (Sandbox Code Playgroud)
人力:: WalkAction:
void WalkAction(){
position.x += 1;
}
Run Code Online (Sandbox Code Playgroud)
CALL_MEMBER_FN(宏):
CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))
问题是当我在调试模式下运行程序时,它完全忽略了带有函数指针的行. - 如果我按语句运行它会"跳过"该行,如果我在walk动作中放置断点它永远不会到达断点.如果我在特定行上放置一个断点,断点就会被推到下一个断点线.
这里发生了什么?
我对C++处理函数指针和成员函数指针的方式感到困惑,所以我在这个示例代码中提炼了我的怀疑:
#include <iostream>
#include <type_traits>
#include <functional>
#include <typeinfo>
using namespace std;
struct asd{ void f(){ } };
void f(){}
template<typename T> void g(T f){
cout<<"T of g is "<<
(is_pointer<T>::value?"pointer":
(is_function<T>::value?"function":
(is_member_function_pointer<T>::value?"member function pointer":
"something else")))<<" -------- ";
typedef typename remove_pointer<T>::type TlessPointer;
cout<<"T of g less a pointer is "<<
(is_pointer<TlessPointer>::value?"pointer":
(is_function<TlessPointer>::value?"function":
(is_member_function_pointer<TlessPointer>::value?"member function pointer":
"something else")))<<endl;
}
int main(){
cout<<"free function ";
g(f);
cout<<endl<<"(multiple times) dereferenced free function (!!!) ";
g(******f);
cout<<endl<<"member function ";
g(&asd::f);
//this won't compile: …Run Code Online (Sandbox Code Playgroud) 我不确定这在C++中是否可行.我知道你可以将指向函数或静态成员函数的指针作为参数传递.我想要一个特定对象的函数指针,这样当函数执行时,它就在对象上完成.
class MyClass
{
public:
MyClass(int id){mId = id;}
void execute(){cout<<mId<<endl;}
private:
int mId;
};
MyClass obj1(1);
MyClass obj2(2);
typedef (Executor)();
Executor ex1 = &obj1::execute();
Executor ex2 = &obj2::execute();
Run Code Online (Sandbox Code Playgroud)
因此,当执行ex1时,应打印"1",如果执行ex2,则打印"2".这可能吗?
c++ pointers member-function-pointers function-pointers functor
我已经设法编写一个模板类来像回调一样工作,从这个问题的接受答案中学习如何定义一般成员函数指针.
我希望有一个字符串键和回调值的映射,以便我可以调用匹配字符串的正确回调.这没关系,但我需要地图来支持来自不同类的回调.现在它只能用于一个类.它可以是任何类,因为模板只是来自同一个类的回调集合.
class Apple {
public:
void Red () {
cout << "aa";
}
};
class Orange {
public:
void Blue () {
cout << "bb";
}
};
template <typename T>
class Callback {
T *obj;
void (T::*ptr) (void);
public:
Callback (T *obj, void (T::*ptr) (void)) : obj (obj), ptr (ptr) {
}
void Call () {
(obj->*ptr) ();
}
};
Run Code Online (Sandbox Code Playgroud)
我可以这样使用它
Apple apple;
Orange orange;
Callback <Apple> callA (&apple, &Apple::Red);
Callback <Orange> callB (&orange, &Orange::Blue);
callA.call (); …Run Code Online (Sandbox Code Playgroud) c++ templates member-function-pointers function-pointers callback
template<typename C, typename Arg>
int foo(C* c, int (C::*func)(Arg), Arg a)
{
c->*func(a);
}
Run Code Online (Sandbox Code Playgroud)
要调用'foo',我们必须同时使用A*和&A :: bar,
foo(A*,&A::bar,var);
Run Code Online (Sandbox Code Playgroud)
有没有办法定义模板(例如作为结构),这样就不需要传递"A*"了?如何定义从"&A :: bar"获取A*的模板?
我遇到了这段代码:
auto f3 = std::bind(&Foo::print_sum, &foo, 95, _1);
Run Code Online (Sandbox Code Playgroud)
在前面的代码中,我们可以将地址运算符应用于成员函数,而没有创建实例对象,这怎么可能?
我想我想要一些不可能的东西,但至少我可以问))
我们可以输入一个函数的指针,它什么都没有,并且没有返回这样的东西.
typedef void (*fpointer)();
Run Code Online (Sandbox Code Playgroud)
如果函数得到一个int,那么
typedef void (*fpointer)(int);
Run Code Online (Sandbox Code Playgroud)
所以我想知道,我可以输入任何函数的指针吗?(非集体成员)
谢谢大家.
编辑:
template <typename T>
struct IsMemberFunctionPointerRaw
{enum{result = 0};};
template <typename T, typename S>
struct IsMemberFunctionPointerRaw<T (S::*)()>
{enum {result = 1};};
Run Code Online (Sandbox Code Playgroud)
...........................................
template <typename T, typename S,
typename P01, typename P02, typename P03, typename P04, typename P05,
typename P06, typename P07, typename P08, typename P09, typename P10,
typename P11, typename P12, typename P13, typename P14, typename P15,
typename P16, typename P17, typename P18, typename P19, typename P20>
struct IsMemberFunctionPointerRaw<T …Run Code Online (Sandbox Code Playgroud) c++ typedef member-function-pointers function-pointers c++11
我想知道是否有可能在类中获取成员函数的地址而不使用作用域的类名.
在下面的例子中,main是获取地址的常规方式,但在func2中,有没有使用类名的方法.要求这样的事情的原因是,将来如果我更改类名,我不必去改变内部.例如:
Class A
{
void func1()
{
}
void func2()
{
/Address of func1/ = &func1; // something like this possible?
}
}
void main()
{
/Address of func1/ = &A::func1;
}
Run Code Online (Sandbox Code Playgroud) 我有一些需要C函数的代码,但是我想实例化一堆类实例并将该类的成员函数作为C函数传递。我需要同时捕获N个实例。我希望我可以作为lambda来做。
这是结果函数的外观(大致):
// This is the code I want to interface with:
typedef void func(ParamClass param); // ParamClass is NOT my class
extern void notMyCode1(func funcArg); // Code I want to call, saves funcArg
extern void notMyCode2() // uses saved funcArgs
// Here is the type of class I want to instantiate:
class MyClass {
public:
MyClass(int arg) : saveArg(arg) {}
int saveArg;
void myFunc(ParamClass param) {
// uses saveArg and param to do the right action
}
};
void …Run Code Online (Sandbox Code Playgroud) 在开始时,有C.
和C有结构,表达和功能来打包它们.这很好.
但是C也有goto和switch case掉线和随后使用的语法,所以可能不那么好.
它也有指针,从别名和指针算术中引起大量咬牙切齿!
但它也有函数指针,允许运行时调度,并随后欢喜.
现在,数据可以指示代码,以及指示数据的代码,并且都是头等(或接近).
对于任何可以指出的东西,可以用同一个指针指出:圣洁的空虚*.
它的荣耀都是平等的.
然后C++来了,并将数据和代码绑定到Object中.
而且,这只是语法糖,因为函数和方法没有那么不同,
(无论Sun或Oracle可能告诉你什么).
Obj-> Foo(int val)与Foo(Obj*this,int val)相同(大约),它们
在神圣的空隙*下仍然相等.
然后,继承,冲突,因为外部Derived类可能会添加到内部Base.
但是,在这些简单的时代,我们找到了一个解决方案:在Derived之前放入每个Base.
然后,使用相同的指针,我们可以指向孩子和父亲.
而且,任何可以指出的东西,都可以指向圣洁的空虚*.
随着虚拟,我们失去了我们的简单,并徘徊了很长时间.
想知道,如何处理钻石,或者不是椭圆形的圆圈.
但是,即使我们抛弃了C的旧租户,每个指令都简化为简单的asm,
我们也接受了,有些东西应该看起来很简单(即使它们很复杂).
因此,我们查看了出现并认为"足够好"的秘密VTables.
在我们引入隐藏数据的同时,我们降低了复杂性.
现在,通过虚拟机进行的任何呼叫都通过VTable重定向.
由于一个类的所有子对象都可以通过单个指针指向,这就足够了.
但即使调度方法发生了变化,我们仍然可以指出所有事情,圣洁无效*.
但后来有人提出,目前很多人都认为这是一个严重的错误:多重继承.
并且一个指针不再足够!两位基础父亲如何才能在一开始?
那么,VTable就不再足够了,因为我们怎么知道要指向哪个子对象!
而现在,钻石的问题比以前更糟糕,没有明显的解决方案,而我们之前的钻石需要现有的代码来应对未来的前景!
因此,必须在每次虚拟呼叫时进行指针调整.
因为Base类可能真的是伪装的MI Derived类,需要进行调整.
因此,对于使用MI的Choice Few的支持,我们都付出了代价.
突然之间,圣洁的空虚*再也无法储存那些简单的糖.
处理这种复杂性的原因是可怕的成员函数指针.
野兽需要它自己的语法,因为其他人都不够.
而且这种语法很少使用,它的优先级如此之低,以至于每次使用都需要parans.
虽然在神圣的标准中,邪恶的议会决定允许这些可怜的东西被投射,
但是当从类型转换为类型时,不调用而不调用行为最不明确!
然而,在语法和贪婪方面颓废,他们是胖子,无法适应无效*.
作为了解要指向的对象的唯一方法是进行调整,
深入嵌入指针,并使用每个VTable查找进行检查.
但兄弟们,这不是必须的.
这种实施的复杂性来自于一种最特殊的决策.
class Base1
{
public:
virtual void foo();
};
class Base2
{
public:
virtual void bar();
};
class Derived: public Base1, public Base2
{
public:
void unrelated();
}
Run Code Online (Sandbox Code Playgroud)
如此处所示,在调用foo()或bar()时必须调整Derived*; 它不能同时指向Base1和Base2,就像简单单继承的情况一样.实际上,从基类调用时,确实无法正确预测需要多少偏移,这就是为什么大多数都有某种机制将其添加到vtable中.
然而: …
c++ oop member-function-pointers multiple-inheritance language-lawyer