我有一个 C++ 函数,它接受 std::function
作为输入参数。
具体来说,std::function<void (const Message&, Error)>
.
在我的用例中,调用者可以绑定(bind) std::function
到自由函数或成员函数。
(我对 std::bind
或 std::function
没有经验,所以我发现值得注意的是,相同的对象类型 std::function<void (const Message&, Error)>
可以绑定(bind)到自由函数以及成员函数 - 后者通过使用 std::bind
。我发现它很有趣,因为它似乎抽象了 difference between a function pointer and a member function pointer (至少它给了我这样的印象))
对于我的调试需求,记录与 std::function
关联的唯一的哈希值会很有用。输入参数。
在这里,我很快意识到我无法逃避自由函数指针和成员函数指针之间的根本区别。
我可以获得底层void (*)(const Message&, Error)
使用 std::function::target<void (*)(const Message&, Error)>()
释放函数指针,它作为一个独特的哈希来满足我的需求。
但如果 std::function<void (const Message&, Error)>
则不起作用。绑定(bind)到成员函数。
在我的脑海里,我推断如果 std::function<void (const Message&, Error)>
绑定(bind)到 class Foo
成员函数,则std::function::target<void (Foo::*)(const Message&, Error)>()
将返回指向成员函数指针的指针——但情况似乎并非如此。
这引出了我的问题:有没有什么方法可以从 std::function
获取唯一的哈希值?实例,无论它绑定(bind)到自由函数还是成员函数?
#include <functional>
#include <iostream>
using namespace std;
struct Message {
int i_;
};
struct Error {
char c_;
};
class Foo {
public:
void print(const Message& m, Error e) {
cout << "member func: " << m.i_ << " " << e.c_ << endl;
}
};
void print(const Message& m, Error e) {
cout << "free func: " << m.i_ << " " << e.c_ << endl;
};
void doWork(function<void (const Message&, Error)> f) {
// I can invoke f regardless of whether it's been bound to a free function or
// a member function...
{
Message m{42};
Error e{'x'};
f(m, e);
}
// ...but since I don't know whether f is bound to a free function or a member
// function, I can't use std::function::target<>() to generically get a
// function pointer, whose (void*) value would have served my need for a
// hash...
{
typedef void (*Fptr)(const Message&, Error);
typedef void (Foo::*Mfptr)(const Message&, Error);
Fptr* fptr = f.target<Fptr>();
Mfptr* mfptr = nullptr;
cout << "free func target: " << (void*)fptr << endl;
if (fptr) {
cout << "free func hash: " << (void*)*fptr << endl;
}
else {
// ...moreover, when f is bound to a Foo member function (using
// std::bind), std::function::target<>() doesn't return a Foo member
// function pointer either...I can't reason why not.
// (this also isn't scalable because in future, f may be bound to a
// class Bar or class Baz member function)
mfptr = f.target<Mfptr>();
cout << "not a free function; checking for a Foo member function" << endl;
cout << "member func target: " << (void*)mfptr << endl;
if (mfptr) {
cout << "member func hash: " << (void*)*mfptr << endl;
}
}
}
}
int main()
{
{
function<void (const Message&, Error)> f = print;
doWork(f);
}
cout << "---" << endl;
{
Foo foo;
function<void (const Message&, Error)> f = bind(&Foo::print,
&foo,
placeholders::_1,
placeholders::_2);
doWork(f);
}
return 0;
}
编译和输出:
$ g++ --version && g++ -g ./main.cpp && ./a.out
g++ (Debian 8.3.0-6) 8.3.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
free func: 42 x
free func target: 0x7ffda4547bf0
free func hash: 0x55db499c51e5
---
member func: 42 x
free func target: 0
not a free function; checking for a Foo member function
member func target: 0
最佳答案
以下代码:
#include <functional>
#include <iostream>
#include <vector>
#include <string>
#include <cstdint>
int f(int a) { return -a; }
int f2(int a) { return a; }
int main() {
std::vector<std::function<int(int)>> fn{
f,
f,
f2,
f2,
[](int a) {return -a;},
[](int a) {return -a;},
[](int a) {return -a;},
};
for (auto&& a : fn) {
const auto t = a.target<int(*)(int)>();
const auto hash = t ?
(size_t)(uintptr_t)(void*)*t :
a.target_type().hash_code();
std::cout << hash << '\n';
}
}
由两个 f 函数、两个 f2 函数和 3 个 lambda 函数组成的初始化 vector 。因此,我们期望两个相同的哈希值,两个相同的哈希值,并且每个 lambda 都是一个新类型 - 3 个不同的哈希值。代码输出:
4198918
4198918
4198932
4198932
11513669940284151167
7180698749978361212
13008242069459866308
关于c++ - 有没有办法创建由 `std::function<>` 包装的函数的哈希值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76114714/