【问题标题】:Function object conversion to function pointer函数对象转换为函数指针
【发布时间】:2015-10-08 19:47:39
【问题描述】:

我正在寻找一种将函数对象转换为函数指针的方法。 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::less<int>这样的std谓词。

我发现的一种方法是将 foo 的调用用 lambda 包装起来。 如果我可以保证 foo 是无状态的并且是 const 我真的不需要 this ptr 和 lambda-capture:

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...);
    };
  }
};

但是这里我不知道如何提供完美的转发, 导致[](Args&amp;&amp;...)[](auto&amp;&amp;...) 无法转换为R(*)(Args...)。 当 args 像 std::unique_ptr&lt;int&gt; 这样不可复制时,这种技巧就会失败。

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

Live example.

任何建议表示赞赏。

【问题讨论】:

    标签: c++ c++11 lambda function-pointers function-object


    【解决方案1】:

    我相信您可以通过以下方式简化您的 to_function_pointer

    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)...);
            }
        }
    };
    

    有几点需要注意。 Args... 是否已经是引用,您正在提供该签名。所以forward&lt;&gt; 仍然会做同样的事情——这个函数恰好不是这里的模板。另外,废弃奇怪的nullptr 演员。这看起来很糟糕——如果我们只需要微不足道的可构造性,我们可以写U{},这对我来说似乎更干净。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-08
      • 2013-03-26
      • 2016-06-03
      • 1970-01-01
      • 2022-01-16
      • 2011-07-31
      • 1970-01-01
      • 2015-11-03
      相关资源
      最近更新 更多