C++ 函数对象到函数指针的转换

C++ 函数对象到函数指针的转换,c++,c++11,lambda,function-pointers,function-object,C++,C++11,Lambda,Function Pointers,Function Object,我正在寻找一种将函数对象转换为函数指针的方法。 Captureless lambda具有隐式转换,允许: using fptr_t = int (*)(int); fptr_t ptr = nullptr; ptr = [](int) { return 2; }; ptr = [](auto) { return 3; }; (*ptr)(42); 我尝试对老式的空类函数对象执行相同的操作,如: struct Foo { int operator()(int) const { return

我正在寻找一种将函数对象转换为函数指针的方法。 Captureless lambda具有隐式转换,允许:

using fptr_t = int (*)(int);
fptr_t ptr = nullptr;
ptr = [](int) { return 2; };
ptr = [](auto) { return 3; };
(*ptr)(42);
我尝试对老式的空类函数对象执行相同的操作,如:

struct Foo {
  int operator()(int) const { return 5; }
} foo;
或std谓词,如
std::less

我发现的一种方法是用lambda包装
foo
的调用。 如果我能保证
foo
是无状态的,并且是常量 我真的不需要这个ptr和lambda捕获:

template <typename R, typename... Args>
struct to_function_pointer<R(Args...)> {
private:
  template <typename T, REQUIRES(std::is_empty<T>::value)>
  static T const& stateless_const() {
    return (*static_cast<T const*>(nullptr));
  }

public:
  using pointer = R (*)(Args...);

  template <typename U>
  pointer operator()(U) const {
    return [](Args... args) {
      return stateless_const<std::decay_t<U>>()(args...);
    };
  }
};
模板
结构到函数指针{
私人:
模板
静态T常量和无状态_常量(){
返回(*static_cast(nullptr));
}
公众:
使用指针=R(*)(Args…);
模板
指针运算符()(U)常量{
返回[](Args…Args){
返回无状态_const()(args…);
};
}
};
但在这里我不知道如何提供完美的转发, 原因
[](Args&&…
[](auto&&…
无法转换为
R(*)(Args…
)。 如果args是不可复制的,比如
std::unique\u ptr
,那么这种技巧就失败了

我知道我可以使用
std::function
,但它有点重,而我正试图得到一个轻量级的解决方案


非常感谢您的建议。

我相信您可以通过以下方式将
简化为\u函数\u指针

template <typename R, typename... Args>
struct to_function_pointer<R(Args...)> {
    using pointer = R(*)(Args...);

    template <typename U, REQUIRES(std::is_empty<U>::value && std::is_trivially_constructible<U>::value)>
    pointer operator()(U ) const
    {
        return [](Args... args) {
            return U{}(std::forward<Args>(args)...);
        }
    }
};
模板
结构到函数指针{
使用指针=R(*)(Args…);
模板
指针运算符()(U)常量
{
返回[](Args…Args){
返回U{}(std::forward(args)…);
}
}
};
没什么值得注意的<代码>参数…是否已经是引用,您正在提供该签名。因此,
forward
仍将执行相同的操作-函数恰好不是这里的模板。此外,请取消奇怪的
nullptr
cast。这看起来很糟糕——如果我们只需要微不足道的可构造性,我们就可以编写
U{}
,这对我来说似乎更干净