Есть ли способ преобразовать std::function
с аргументом T*
в аналогичный с аргументом 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();
}
Изменить: Решение с определенным UDB, но правильным поведением. :-/
It seems possible since the calls should be compatible at the binary level.
Хотя оба указателя (вероятно) не различаются в памяти, в некотором роде это определенно UB. Что должна делать вызываемая функция с переданным not-T там, где ожидается T? ... Я не понимаю, почему вы беспокоитесь о потере безопасности типов, когда вы собираетесь ее потерять. - person deviantfan   schedule 13.11.2015void*
и обратно имеют правильный тип, я думаю, что это законно. ctor предотвращает получение не-T, но если бы это было не так, тогда это был бы UDB. Я не понимаю, почему вы говорите, что это не безопасно для типов. - person Praxeolitic   schedule 13.11.2015Producer
? О, и в реальной ситуации, когда это произошло, у меня было две функции, которые использовалиvoid*
. - person Praxeolitic   schedule 13.11.2015std::function
сам обрабатывает стирание фактического типа объекта функции. Здесь нам просто нужно одно преобразование адреса объекта, которое не меняет того, какstd::function
вызывает вызываемый объект (как бы это ни было). - person Praxeolitic   schedule 13.11.2015