举例1:普通函数指针:
int(*fun)(double, int);
fun = [](double a, int b) {
cout << a << endl;
cout << b << endl;
return 3;
};
int x = fun(34, 123);
typedef定义函数指针类型:
typedef int(*padd)(int, int, int);
int add(int a, int b, int d)
{
return a + b + d;
}
int mul(int a, int b, int d)
{
return a * b * d;
}
int main()
{
padd p1 = add; //p1为padd类型的变量
p1(1, 2, 3);
padd p2 = mul; //p2为padd类型的变量
p2(1, 2, 3);
return 0;
}
如果不使用typedef定义函数指针类型,则不能声明变量。
举例2:类成员函数指针
#include <iostream>
using namespace std;
class A {
public:
A() = default;
int SayHello(int a)
{
cout << a << endl;
return 100;
}
};
typedef int(A::*FP)(int); //类成员函数指针,要加一个类的作用域,四饼运算符,哈哈哈
int main()
{
FP fp = &A::SayHello;
A a;
int x = (a.*fp)(3); //*fp可以称为解引用,取得函数名字(a.*fp)
cout << x << endl;
return 0;
}
再举个例子:
假设我们有一个类Person,其中有一个成员函数void sayHello(),我们可以使用类成员函数指针来实现回调机制:
#include <iostream>
class Person {
public:
void sayHello() {
std::cout << "Hello, I'm a person!" << std::endl;
}
};
void callback(void (Person::*func)(), Person* p) {
(p->*func)();
}
int main() {
Person p;
callback(&Person::sayHello, &p);
return 0;
}
在这个例子中,callback函数接受一个类成员函数指针和一个Person对象的指针作为参数,当函数被调用时,它会使用指针调用Person对象的成员函数。
通过这种方式,我们可以将一个成员函数作为参数传递给另一个函数,从而实现回调机制,这在事件处理和异步编程中非常常见。
typedef的作用,定义一个新的类型:
class Foo {
public:
float bar(int x) { return x * 3.14f; }
};
typedef float (Foo::*BarPtr)(int);
In this case, BarPtr is now a type that can hold a pointer to the bar member function of Foo.
这里的BarPtr就是新的类型,可以用来接收类的成员函数指针。
https://blog.molecular-matters.com/2011/09/19/generic-type-safe-delegates-and-events-in-c/
https://skypjack.github.io/2019-01-25-delegate-revised/
https://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible
https://www.ibm.com/docs/en/zos/2.3.0?topic=only-explicit-specialization-c
http://www.lucadavidian.com/2020/11/20/c-delegates/
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
template<typename T>
void f(T&& t)
{
if (std::is_same<int, T>::value) //T&&
{
cout << "int" << endl;
}
if (std::is_same<int&, T>::value) //T&&
{
cout << "int&" << endl;
}
if (std::is_same<int&&, T>::value) //T&&
{
cout << "int&&" << endl;
}
}
template<typename T>
T sum(T t)
{
return t;
}
template<typename T, typename ... Types>
T sum(T first, Types ... rest)
{
int count = sizeof...(rest);
return first + sum<T>(rest...);
}
//template <class... T>
//void f2(T... args)
//{
// cout << sizeof...(args) << endl; //打印变参的个数
//}
template <typename...> class Foo;
template <typename A, typename B>
class Foo<A, B>
{
public:
void output() {
std::cout << a_ << b_ << '\n';
}
A a_;
B b_;
};
template <typename A, typename B, typename C>
class Foo<A, B, C>
{
public:
void output() {
std::cout << a_ << b_ << c_ << '\n';
}
A a_;
B b_;
C c_;
};
template<typename>
class FF;
template<typename T, typename ...B>
class FF<T(B...)> {
public:
void Show()
{
int count = sizeof...(B);
}
int a;
};
using xxx = FF<int(int, int, int)>;
xxx ddd{};
template <typename> class Foo2;
template <typename A, typename B>
class Foo2<void(A, B)> {
};
template <typename A, typename B, typename C>
class Foo2<void(A, B, C)> {
};
#define DefineX(name) cout<<23.name<<endl;
void call(int a)
{
std::cout << "hello" << endl;
}
void my_func(int) { /* ... */ }
struct my_class {
void my_member(int) { /* ... */ }
};
class Student
{
public:
void SayHello(int b)
{
cout << "hello" << endl;
}
};
typedef void(*FunctionPointer)(int);
typedef void (Student::*FunctionPointer2)(int);
void nihao(int a)
{
int bb = a + 1;
}
using proto_fn_type = int(string, int&&...);
proto_fn_type* _caller;
int main()
{
_caller = [](string a, int&&...)->int {
string b = a;
cout << "hello" << endl;
return 321;
};
int xdd = _caller("hello", 2);
FunctionPointer p = nihao;
p(3);
Student s;
FunctionPointer2 p2 = &(Student::SayHello);
(s.*p2)(3);
FF<int(int, int)> aaa{
aaa.a = 3
};
Foo2<void(int, int)> f2{};
Foo2<void(int, int, std::string)> f3;
Foo<int, int> aa{
aa.a_ = 3,
aa.b_ = 4,
};
int(*fun)(double, int);
fun = [](double a, int b) {
cout << a << endl;
cout << b << endl;
return 12;
};
int x = fun(34, 123);
std::cin.get();
return 0;
}
函数指针延伸,委托类:
#include <iostream>
#include <iomanip>
#include <string>
#include "Test.h"
using namespace std;
template<typename>
class XDelegate;
template<typename Ret, typename ...Args>
class XDelegate<Ret(Args...)>
{
using proto_fn_type = Ret(void*);
public:
Ret operator()()
{
return _caller(_this);
}
template<auto method, typename Type>
void connect(Type* instance) noexcept
{
_this = instance;
_caller = [](void* data)->Ret
{
Type* payload = static_cast<Type*>(data);
return Ret(std::invoke(method, payload));
};
}
private:
proto_fn_type* _caller;
void* _this;
};
int f(int* a)
{
return *a;
}
int main()
{
XDelegate<int(int)> b{};
int p = 12345;
b.connect<&f, int>(&p);
int a = b();
return 0;
}