C++11可变模板函数调用转发
C++11 variadic template function call forwarding
我正在尝试创建一个C++11模板函数,该函数将在两种约定之间转换函数调用:第一种是使用Variant(注意:Variant是多态类型,是IntVariable、DoubleVariant等子类的基础),第二种是C函数调用。
我们在编译时知道每一条信息:参数计数是参数的数量,参数/返回类型取决于"cfunc"变量类型。
// We will assume that the two following functions are defined with their correct
// specializations.
template < typename T >
Variant * convertToVariant( T t );
template < typename T >
T convertFromVariant( Variant * variant );
// The following function is incomplete, the question is how to convert the
// variant parameters into a C function call ?
template < typename Return, typename... Arguments >
Variant * wrapCFunction< Return cfunc( Args... ) >(int argc, Variant ** argv) {
// Here comes the magic call of cfunc, something like :
if ( argc != mpl::count< Args... >::value )
throw std::runtime_error( "bad argument count" );
return cfunc( convertFromVariant< Args... >( argv[ X ] )... );
}
// Example use case :
int foo( int a, int b );
int main(void) {
int argc = 2;
Variant * argv[2] = { new IntVariant( 5 ), new IntVariant( 6 ) };
Variant * res = wrapCFunction< foo >( argc, argv );
IntVariant * intRes = dynamic_cast< IntVariant >( res );
return intRes ? intRes->value : -1;
}
使用索引技巧,这很容易:
template<unsigned...> struct indices{};
template<unsigned N, unsigned... Is>
struct indices_gen : indices_gen<N-1, N-1, Is...>{};
template<unsigned... Is>
struct indices_gen<0, Is...> : indices<Is...>{};
// assuming the parameters were actually like this
template<typename Return, typename... Args, unsigned... Is>
Variant* wrapCFunction(Return (*cfunc)(Args...), int argc, Variant** argv, indices<Is...>) {
return cfunc(convertFromVariant<Args>(argv[Is])...);
}
template<typename Return, typename... Args>
Variant* wrapCFunction(Return (*cfunc)(Args...), int argc, Variant** argv) {
if (argc != sizeof...(Args))
throw std::runtime_error("bad argument count");
return wrapCFunction(cfunc, argc, argv, indices_gen<sizeof...(Args)>());
}
请注意代码中的一些更改。首先,sizeof...(Args)
生成包中的参数数量。其次,我修复了函数的签名,以传递cfunc
作为实际参数。
class Variant;
template < typename T > Variant * convertToVariant( T t );
template < typename T > T convertFromVariant( Variant * variant );
template <typename Return, typename... Arguments>
struct WrapCFunctionImpl {
template<int argsToAdd, int... argIndexes>
struct Impl {
typedef typename Impl<argsToAdd - 1, argIndexes..., sizeof...(argIndexes)>::Type Type;
};
};
template <typename Return, typename... Arguments>
template <int... argIndexes>
struct WrapCFunctionImpl<Return, Arguments...>::Impl<0, argIndexes...> {
typedef Impl Type;
static Variant* run(Return cfunc( Arguments... ), Variant ** argv) {
return convertToVariant( cfunc( convertFromVariant<Arguments>( argv[argIndexes] )... ) );
}
};
template < typename Return, typename... Arguments >
Variant * wrapCFunction(Return cfunc( Arguments... ), Variant ** argv) {
return WrapCFunctionImpl<Return,Arguments...>::template Impl<sizeof...(Arguments)>::Type::run(cfunc, argv);
}
int foo(int, int);
Variant *f(Variant** x) {
return wrapCFunction(foo, x);
}
这里的大部分困难是递归生成数组中的索引。也许有更简单的方法,但这是有效的。
相关文章:
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 变量没有改变?通过向量的函数调用
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 模板函数调用
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 析构函数调用
- 成员函数调用和C++对象模型
- 使用共享指针的函数调用,其对象应为 const
- C++:编译时检查匹配的函数调用对?
- 为什么调用转发引用构造函数而不是复制构造函数?
- 将函数调用转发到成员变量
- C++11可变模板函数调用转发
- 转发构造函数调用基类的复制构造函数2次
- C++:转发模板成员函数调用失败
- C++将非模板成员函数调用转发到模板函数
- 将函数调用转发给成员是不好的做法吗?
- 何时应该转发函数调用