如何检查函数的参数类型? [英] How to inspect the types of a function's parameters?

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

问题描述

我有一个应用程序,其中我正在建立一个函数 marshal_and_apply ,它调用一些其他函数(或函子), f 有一些参数。 marshal_and_apply 的作业是根据 f 的参数类型对参数应用一些特殊的封送处理。 / p>

如果 f 的某个参数是特殊类型, marshal_me& ,然后 marshal_and_apply 将通过一些特殊分配的存储编组参数,然后将其传递给 f 。为了执行分配,在任何可以编组之前,所有参数的存储需求必须已知为 marshal_and_apply






一些示例:

 模板< typename函数,typename ... Args> 
void marshal_and_apply(Function f,Args ... args);

void func1(int x,int y);
void func2(marshal_me< int> x,int y);
void func3(marshal_me< int> x,marshal_me< int> y,marshal_me< int> z)

//这个调用相当于:
// func1(7,13)
marshal_and_apply(func1,7,13);

//这个调用相当于:
// auto storage = my_allocator(sizeof(int));
// auto x = marshal_me< int>(7,storage);
// func2(x,13);
marshal_and_apply(func2,7,13);

//这个调用相当于:
// auto storage = my_allocator(sizeof(int)+ sizeof(int)+ sizeof(int));
// auto x = marshal_me< int>(7,storage);
// auto y = marshal_me< int>(13,storage + sizeof(int));
// auto z = marshal_me< int>(42,storage + sizeof(int)+ sizeof(int));
// func3(x,y,z);
marshal_and_apply(func3,7,13,42);






为了解决这个问题, c $ c> marshal_and_apply 需要一种机制来检查 f 的参数类型。我怀疑这通常是不可能的,但是可以识别特殊的一组类型(在这种情况下, marshal_me )中的一个是可转换的到特定参数的类型。



如何构建 marshal_and_apply

解决方案

可能类似这样:

  template< ,typename ... Args> 
void marshal_and_apply(function f,Args& ... args)
{
f(InspectAndModify< Args> :: process(sizeof ...(Args),std :: forward& ; Args(args))...);
}



现在定义:

  template< typename T> struct InspectAndModify 
{
static T&&过程(unsigned int N,T& t)
{
return std :: forward< T&
}
};

template< typename T> struct InspectAndModify< marshal_me< T>>
{
static T&& process(unsigned int N,marshal_me< T&& m)
{
/ * ... * /
}
}






完全不同的这种方法首先剖析函数签名,然后对每对类型执行静态变换,这是您可以插入 marshal_me specialization:

 模板< typename T> struct marshal_me {marshal_me(T){}}; 

template< typename To,typename From> struct static_transform;

template< typename T> struct static_transform< T,T>
{
static T go(T t){return t; }
};

template< typename T> struct static_transform< T,T&>
{
static T go(T& t){return t; }
};

template< typename T> struct static_transform< marshal_me< T>,T>
{
static marshal_me< T> go(T& t){return std :: forward T(t); }
};

template< typename T,typename ... Args>
struct marshal_impl
{
template< typename ... Urgs>
static T go(T(* f)(Urgs ...),Args& ... args)
{
return f(static_transform< Urgs,Args> :: go(std :: forward< Args>(args))...);
}
};

template< typename Function,typename ... Args>
void marshal_and_apply(function f,Args& ... args)
{
marshal_impl< void,Args ...> :: go(static_cast< typename std :: decay< ; function> :: type>(f),
std :: forward< Args>(args)...)
}


I have an application where I'm building a function, marshal_and_apply, which calls some other function (or functor), f with some arguments. marshal_and_apply's job is to apply some special marshaling for the arguments depending on the type of f's parameters.

If one of f's parameters is of a special type, marshal_me<T>, then marshal_and_apply will marshal the parameter through some specially allocated storage before passing it to f. In order to perform the allocation, the storage requirements of all the parameters must be known to marshal_and_apply before any can be marshaled.


Some examples:

template<typename Function, typename... Args>
void marshal_and_apply(Function f, Args... args);

void func1(int x, int y);
void func2(marshal_me<int> x, int y);
void func3(marshal_me<int> x, marshal_me<int> y, marshal_me<int> z);

// this call would be equivalent to:
// func1(7,13)
marshal_and_apply(func1, 7, 13);

// this call would be equivalent to:
// auto storage = my_allocator(sizeof(int));
// auto x = marshal_me<int>(7, storage);
// func2(x, 13);
marshal_and_apply(func2, 7, 13);

// this call would be equivalent to:
// auto storage = my_allocator(sizeof(int) + sizeof(int) + sizeof(int));
// auto x = marshal_me<int>(7, storage);
// auto y = marshal_me<int>(13, storage + sizeof(int));
// auto z = marshal_me<int>(42, storage + sizeof(int) + sizeof(int));
// func3(x,y,z);
marshal_and_apply(func3, 7, 13, 42);


To solve this problem, it seems that marshal_and_apply requires a mechanism to inspect the types of f's parameters. I suspect this isn't possible in general, but it may be possible to recognize whether one of a special set of types (in this case, marshal_me<T>) is convertible to the type of a particular parameter.

How should I build marshal_and_apply?

解决方案

Maybe something like this:

template<typename Function, typename... Args>
void marshal_and_apply(Function f, Args &&... args)
{
    f(InspectAndModify<Args>::process(sizeof...(Args), std::forward<Args>(args))...);
}

Now define:

template <typename T> struct InspectAndModify
{
    static T&& process(unsigned int N, T && t)
    {
        return std::forward<T>(t);
    }
};

template <typename T> struct InspectAndModify<marshal_me<T>>
{
     static T&& process(unsigned int N, marshal_me<T> && m)
     {
         /* ... */
     }
};


Something completely different: This approach first dissects the function signature, and then performs a "static transform" on each pair of types, which is where you can insert the marshal_me specialization:

template <typename T> struct marshal_me { marshal_me(T) { } };

template <typename To, typename From> struct static_transform;

template <typename T> struct static_transform<T, T>
{
  static T go(T t) { return t; }
};

template <typename T> struct static_transform<T, T&>
{
  static T go(T & t) { return t; }
};

template <typename T> struct static_transform<marshal_me<T>, T>
{
  static marshal_me<T> go(T && t) { return std::forward<T>(t); }
};

template<typename T, typename... Args>
struct marshal_impl
{
  template <typename ...Urgs>
  static T go(T(*f)(Urgs...), Args &&... args)
  {
    return f(static_transform<Urgs, Args>::go(std::forward<Args>(args))...);
  }
};

template<typename Function, typename... Args>
void marshal_and_apply(Function f, Args &&... args)
{
  marshal_impl<void, Args...>::go(static_cast<typename std::decay<Function>::type>(f),
                                  std::forward<Args>(args)...);
}

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

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