如何检查函数参数的类型?
How to inspect the types of a function's parameters?
我有一个应用程序,我正在构建一个函数marshal_and_apply
,它用一些参数调用其他函数(或函子)f
。marshal_and_apply
的工作是根据f
参数的类型对参数应用一些特殊的封送处理。
如果f
的一个参数是特殊类型marshal_me<T>
,那么marshal_and_apply
将通过一些专门分配的存储封送该参数,然后将其传递给f
。为了执行分配,marshal_and_apply
必须知道所有参数的存储要求,然后才能封送任何参数。
一些例子:
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);
为了解决这个问题,marshal_and_apply
似乎需要一种机制来检查f
的参数类型。我怀疑这在一般情况下是不可能的,但可以识别一组特殊类型(在本例中为marshal_me<T>
)中的一个是否可以转换为特定参数的类型。
我应该如何构建marshal_and_apply
?
也许是这样的:
template<typename Function, 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&& 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)
{
/* ... */
}
};
完全不同的东西:这种方法首先解析函数签名,然后对每对类型执行"静态转换",在这里可以插入marshal_me
专用化:
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)...);
}
相关文章:
- 扩展C++生成的代码的模板参数类型名称
- 如何在 c++ 中定义接受不同参数类型的函数向量?
- 在 C++ 中运行时调用模板时,是否可以切换模板的参数类型?
- 将函数参数类型声明为 auto
- 将函数的参数 - 签名从使用 'std::function<T>' 转换为模板参数类型
- 在 C++17 中调用具有不同参数类型的构造函数
- 具有先前参数类型匹配的参数包
- 我想知道为什么"std::unique_ptr<int> foo(新 int)"是合法的,因为"std::<int>unique_ptr"要求输入参数类型应该是"int"?
- 将可变参数类型列表的扩展打包为复杂类型的初始值设定项列表 - 合法吗?
- MSVC 错误:4 个重载中的任何一个都无法转换所有参数类型
- 使用constexpr + auto作为返回和参数类型的奇怪类型推导
- 如何从第一个参数推断第二个参数类型?
- C++模板函数中,指定回调函子/lambda 的参数类型,同时仍允许内联?
- 如何用不同的参数类型和数字回调函数
- C++stoi:这两个重载都无法转换所有参数类型
- 为什么std::{container}::template不能推导其参数类型
- 为模板参数类型中的新对象分配内存
- 为指向成员模板参数的指针推导额外模板参数类型的紧凑方式
- 使用std::conditional中的模板来确定函数参数类型
- C++中的短参数类型