【发布时间】:2015-11-13 16:29:21
【问题描述】:
有没有办法将具有T* 参数的std::function 转换为具有void* 参数的类似参数?这似乎是可能的,因为调用应该在二进制级别兼容。
例如,我怎样才能在不将Producer 转换为模板或失去类型安全性的情况下完成这项工作?
#include <functional>
struct Producer {
// produces an int from a callable and an address
template<class Src>
Producer(Src& src, std::function<int (Src*)> f)
: arg_(&src),
f_(f)
{}
int operator()() {
return f_(arg_);
}
// type erasure through void* but still type safe since ctor
// checks that *arg_ and f are consistent
void* arg_;
std::function<int (void*)> f_;
};
int func1(char* c) {
return *c;
}
int func2(int* i) {
return *i;
}
int try_it() {
char c = 'a';
char i = 5;
// we want to make these work
Producer p1(c, func1);
Producer p2(i, func2);
// but we still want this to fail to compile
// Producer p3(c, func2);
return p1() + p2();
}
编辑:Solution 具有明确的 UDB,但行为正确。 :-/
【问题讨论】:
-
It seems possible since the calls should be compatible at the binary level.虽然两个指针在内存中(可能)没有什么不同,但它在某种程度上肯定是 UB。被调用的函数应该如何处理在预期 T 的地方传递的非 T? ...我不明白你为什么在打算失去类型安全时担心失去它。 -
@deviantfan 你确定 UDB 吗?只要来往于
void*的演员有正确的类型,我认为这是合法的。 ctor 阻止获取非 T,但如果它没有然后,它将是 UDB。我不明白你为什么说这不是类型安全的。 -
我会使用 bind 使函数调用具有相同的签名。这样,Producer 只是调用了一个没有附加参数的函数对象。
-
@AnonMail 有没有办法做到这一点,而
Producer的用户没有这样做?哦,在出现这种情况的实际情况下,我有两个使用void*的函数。
标签: c++ type-conversion c++14 std-function