为“make_function"推断 lambda 或任意可调用的调用签名;

Inferring the call signature of a lambda or arbitrary callable for quot;make_functionquot;(为“make_function推断 lambda 或任意可调用的调用签名;)
本文介绍了为“make_function"推断 lambda 或任意可调用的调用签名;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

在某些情况下,希望能够对可调用对象进行类型擦除(例如,函数、函数指针、带有 operator()、lambda、mem_fn 的对象实例),例如在 使用带有 C++11 lambdas 的 Boost 适配器 中,其中复制-需要可赋值和默认构造的类型.

In some situations it's desirable to be able to type-erase a callable (e.g. function, function pointer, object instance with operator(), lambda, mem_fn), for instance in Using Boost adaptors with C++11 lambdas where a copy-assignable and default-constructible type is required.

std::function 是理想的,但似乎没有办法自动确定实例化类模板的签名std::function 与.有没有一种简单的方法来获取任意可调用的函数签名和/或将其包装在适当的 std::function 实例化实例(即 make_function 函数模板)中?

std::function would be ideal, but there seems to be no way to automatically determine what signature to instantiate the class template std::function with. Is there an easy way to get the function signature of an arbitrary callable and/or wrap it in an appropriate std::function instantiation instance (i.e. a make_function function template)?

具体来说,我正在寻找其中之一

Specifically, I'm looking for one or other of

template<typename F> using get_signature = ...;
template<typename F> std::function<get_signature<F>> make_function(F &&f) { ... }

这样 make_function([](int i) { return 0; }) 返回一个 std::function.显然,如果一个实例可以用多个签名调用(例如,具有多个、模板或默认参数 operator()s 的对象),这将不会起作用.

such that make_function([](int i) { return 0; }) returns a std::function<int(int)>. Obviously this wouldn't be expected to work if an instance is callable with more than one signature (e.g. objects with more than one, template or default-parameter operator()s).

Boost 很好,虽然不是过于复杂的非 Boost 解决方案是首选.

Boost is fine, although non-Boost solutions that aren't excessively complex are preferred.

回答我自己的问题.

推荐答案

我想出了一个相当讨厌的非库解决方案,利用 lambdas 具有 operator() 的事实:

I've come up with a fairly nasty non-library solution, using the fact that lambdas have operator():

template<typename T> struct remove_class { };
template<typename C, typename R, typename... A>
struct remove_class<R(C::*)(A...)> { using type = R(A...); };
template<typename C, typename R, typename... A>
struct remove_class<R(C::*)(A...) const> { using type = R(A...); };
template<typename C, typename R, typename... A>
struct remove_class<R(C::*)(A...) volatile> { using type = R(A...); };
template<typename C, typename R, typename... A>
struct remove_class<R(C::*)(A...) const volatile> { using type = R(A...); };

template<typename T>
struct get_signature_impl { using type = typename remove_class<
    decltype(&std::remove_reference<T>::type::operator())>::type; };
template<typename R, typename... A>
struct get_signature_impl<R(A...)> { using type = R(A...); };
template<typename R, typename... A>
struct get_signature_impl<R(&)(A...)> { using type = R(A...); };
template<typename R, typename... A>
struct get_signature_impl<R(*)(A...)> { using type = R(A...); };
template<typename T> using get_signature = typename get_signature_impl<T>::type;

template<typename F> using make_function_type = std::function<get_signature<F>>;
template<typename F> make_function_type<F> make_function(F &&f) {
    return make_function_type<F>(std::forward<F>(f)); }

有什么可以简化或改进的想法吗?有什么明显的错误吗?

Any ideas where this can be simplified or improved? Any obvious bugs?

这篇关于为“make_function"推断 lambda 或任意可调用的调用签名;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Why does C++ compilation take so long?(为什么 C++ 编译需要这么长时间?)
Why is my program slow when looping over exactly 8192 elements?(为什么我的程序在循环 8192 个元素时很慢?)
C++ performance challenge: integer to std::string conversion(C++ 性能挑战:整数到 std::string 的转换)
Fast textfile reading in c++(在 C++ 中快速读取文本文件)
Is it better to use std::memcpy() or std::copy() in terms to performance?(就性能而言,使用 std::memcpy() 或 std::copy() 更好吗?)
Does the C++ standard mandate poor performance for iostreams, or am I just dealing with a poor implementation?(C++ 标准是否要求 iostreams 性能不佳,或者我只是在处理一个糟糕的实现?)