gpt4 book ai didi

c++ - std::function 的模板参数是如何工作的? (执行)

转载 作者:IT老高 更新时间:2023-10-28 13:59:01 25 4
gpt4 key购买 nike

Bjarne Stroustrup 的主页 (C++11 FAQ) 中:

struct X { int foo(int); };

std::function<int(X*, int)> f;
f = &X::foo; //pointer to member

X x;
int v = f(&x, 5); //call X::foo() for x with 5

它是如何工作的? std::function如何调用foo成员函数

模板参数是int(X*, int),是&X::foo成员函数指针转换成< em>非成员函数指针?!

(int(*)(X*, int))&X::foo //casting (int(X::*)(int) to (int(*)(X*, int))

澄清一下:我知道我们不需要转换任何指针来使用 std::function,但我不知道 std::function< 的内部结构如何/em> 处理 成员函数指针非成员函数指针 之间的这种不兼容性。我不知道标准如何允许我们实现类似 std::function 的东西!

最佳答案

在得到其他答案和评论的帮助,并阅读了GCC源代码和C++11标准后,我发现可以解析一个函数类型(它的返回类型和它的参数类型)通过使用部分模板特化函数重载

以下是一个简单(且不完整)的示例,用于实现类似 std::function:

template<class T> class Function { };

// Parse the function type
template<class Res, class Obj, class... ArgTypes>
class Function<Res (Obj*, ArgTypes...)> {
union Pointers {
Res (*func)(Obj*, ArgTypes...);
Res (Obj::*mem_func)(ArgTypes...);
};

typedef Res Callback(Pointers&, Obj&, ArgTypes...);

Pointers ptrs;
Callback* callback;

static Res call_func(Pointers& ptrs, Obj& obj, ArgTypes... args) {
return (*ptrs.func)(&obj, args...);
}

static Res call_mem_func(Pointers& ptrs, Obj& obj, ArgTypes... args) {
return (obj.*(ptrs.mem_func))(args...);
}

public:

Function() : callback(0) { }

// Parse the function type
Function(Res (*func)(Obj*, ArgTypes...)) {
ptrs.func = func;
callback = &call_func;
}

// Parse the function type
Function(Res (Obj::*mem_func)(ArgTypes...)) {
ptrs.mem_func = mem_func;
callback = &call_mem_func;
}

Function(const Function& function) {
ptrs = function.ptrs;
callback = function.callback;
}

Function& operator=(const Function& function) {
ptrs = function.ptrs;
callback = function.callback;
return *this;
}

Res operator()(Obj& obj, ArgTypes... args) {
if(callback == 0) throw 0; // throw an exception
return (*callback)(ptrs, obj, args...);
}
};

用法:

#include <iostream>

struct Funny {
void print(int i) {
std::cout << "void (Funny::*)(int): " << i << std::endl;
}
};

void print(Funny* funny, int i) {
std::cout << "void (*)(Funny*, int): " << i << std::endl;
}

int main(int argc, char** argv) {
Funny funny;
Function<void(Funny*, int)> wmw;

wmw = &Funny::print; // void (Funny::*)(int)
wmw(funny, 10); // void (Funny::*)(int)

wmw = &print; // void (*)(Funny*, int)
wmw(funny, 8); // void (*)(Funny*, int)

return 0;
}

关于c++ - std::function 的模板参数是如何工作的? (执行),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3534812/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com