正确使用std :: function :: target

时间:2018-01-10 10:14:17

标签: c++ c++11 c++17

任何人都可以帮我实现下面的test功能,以便它接受任何Callablestd::function,如果true,则返回std::function目标是可赎回?我一直在尝试各种各样的事情,但是它们都没有一直在工作,我甚至无法弄明白为什么他们为他们工作的案件工作。

#include <type_traits>
#include <iostream>
#include <functional>

int foo(int) {return 0;}
int faz(int) {return 0;}

struct {
    int operator()(int) {return 0;}
} bar, baz;

template<class F1, class F2>
bool
test(F1&& f1, std::function<F2> f2) {
    //return f2.template target<F1>() == f1;
    //return f2.template target<F2>() == &f1;
    //return *f2.template target<std::add_pointer_t<F1>>() == &f1;
    //return *f2.template target<std::add_pointer_t<F2>>() == &f1;
    //return *f2.template target<std::add_pointer_t<F1>>() == f1;
    //...
}

int main() {
    std::function<int(int)> f{foo};
    std::cout << test(foo, f) << std::endl;
    std::cout << test(faz, f) << std::endl;
    f = bar;
    std::cout << test(bar, f) << std::endl;
    std::cout << test(baz, f) << std::endl;
}

http://coliru.stacked-crooked.com/a/11346a171199af81

1 个答案:

答案 0 :(得分:6)

template<class F1, class F2>
bool test(F1&& f1, std::function<F2> f2) {
  auto* ptr =  f2.template target<std::decay_t<F1>>();
  if (!ptr) return false;
  return *ptr == f1;
}

这对lambdas不起作用,因为lambdas没有operator==

这对你的结构不起作用,因为它没有operator==

它适用于函数指针,因为它们有operator==

struct bob {
  int operator()(int) {return 0;}
  bool operator==(bob const& o)const{return true;}
} bar, baz;

现在可以了。当然,barbaz的比较等于任何bob

现在,函数存储了传递它的任何内容的副本。因此,您无法将函数中存储的函数的地址与其复制的函数的地址进行比较,并获得有用的结果。

std::ref将指针包起来作为参考。