获取lambda参数类型 [英] Get lambda parameter type

查看:181
本文介绍了获取lambda参数类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要某种方式获得lambda函数的第一个参数类型,这是否可能?

I would like some way to get the first parameter type of a lambda function, is this possible?

例如。

而不是:

template<typename T>
struct base
{
     virtual bool operator()(T) = 0;
}

template<typename F, typename T>
struct filter : public base<T>
{
     virtual bool operator()(T) override {return /*...*/ }
};

template<typename T, typename F>
filter<T> make_filter(F func)
{
      return filter<F, T>(std::move(func));
}

auto f = make_filter<int>([](int n){return n % 2 == 0;});

我想:

template<typename F>
struct filter : public base<typename param1<F>::type>
{
     bool operator()(typename param1<F>::type){return /*...*/ }
};

template<typename F>
filter<F> make_filter(F func)
{
      return filter<F>(std::move(func));
}

auto f = make_filter([](int n){return n % 2 == 0;});

根据Xeo的答案,这是我在VS2010工作:

Based on Xeo's answer this is what I got working in VS2010:

template<typename FPtr>
struct arg1_traits_impl;

template<typename R, typename C, typename A1>
struct arg1_traits_impl<R (C::*)(A1)>{typedef A1 arg1_type;};

template<typename R, typename C, typename A1>
struct arg1_traits_impl<R (C::*)(A1) const>{typedef A1 arg1_type;};

template<typename T>
typename arg1_traits_impl<T>::arg1_type arg1_type_helper(T);

template<typename F>
struct filter : public base<typename std::decay<decltype(detail::arg1_type_helper(&F::operator()))>::type>
{
    bool operator()(typename std::decay<decltype(detail::arg1_type_helper(&F::operator()))>::type){return /*...*/ }
};

template<typename T, typename F>
filter<F> make_filter(F func)
{
      return filter<F>(std::move(func));
}



我试过简化代码,但任何尝试似乎打破了。

I've tried simplifying the the code, but any attempt seems to break it.

推荐答案

最简单的选项就是让一个模板本身:

The easiest option would be to just make the operator() a template itself:

template<typename F>
struct filter
{
     template<class Arg>
     void operator(Arg&& arg){
       // use std::forward<Arg>(arg) to call the stored function
     }
};

template<typename F>
filter<F> make_filter(F func)
{
      return filter<F>(std::move(func));
}

auto f = make_filter([](int n){return n % 2 == 0;});






现在, ,以下代码应该正常工作。但是,它不与MSVC10感谢一个错误:


Now, theoretically, the following code should just work. However, it doesn't with MSVC10 thanks to a bug:

#include <iostream>
#include <typeinfo>

template<class FPtr>
struct function_traits;

template<class T, class C>
struct function_traits<T (C::*)>
{
    typedef T type;
};

template<class F>
void bar(F f){
  typedef typename function_traits<
      decltype(&F::operator())>::type signature;
  std::cout << typeid(signature).name();
}

int main(){
    bar([](int n){ return n % 2 == 0; });
}

这里是一个关于如何看起来与GCC的例子。然而,MSVC10只是不编译代码。请参见此问题我的进一步详细。基本上,MSVC10不将 decltype(& F :: operator())视为依赖类型。这是一个在聊天讨论中设计的解决方案:

Here's an example on how it would look with GCC. MSVC10, however, simply doesn't compile the code. See this question of mine for further detail. Basically, MSVC10 doesn't treat decltype(&F::operator()) as a dependent type. Here's a work-around that was devised in a chat discussion:

#include <iostream>
#include <typeinfo>
#include <type_traits>

template<class FPtr>
struct function_traits;

template<class R, class C, class A1>
struct function_traits<R (C::*)(A1)>
{   // non-const specialization
    typedef A1 arg_type;
    typedef R result_type;
    typedef R type(A1);
};

template<class R, class C, class A1>
struct function_traits<R (C::*)(A1) const>
{   // const specialization
    typedef A1 arg_type;
    typedef R result_type;
    typedef R type(A1);
};

template<class T>
typename function_traits<T>::type* bar_helper(T);

template<class F>
void bar(F f){
  typedef decltype(bar_helper(&F::operator())) fptr;
  typedef typename std::remove_pointer<fptr>::type signature;
  std::cout << typeid(signature).name();
}

int main(){
    bar([](int n){ return n % 2 == 0; });
}

这篇关于获取lambda参数类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆