Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;11可变模板函数呼叫转移_C++_Templates_C++11_Variadic Templates - Fatal编程技术网

C++ C++;11可变模板函数呼叫转移

C++ C++;11可变模板函数呼叫转移,c++,templates,c++11,variadic-templates,C++,Templates,C++11,Variadic Templates,我试图弄清楚如何创建一个C++11模板函数,它将在两个约定之间转换函数调用:第一个是使用Variant(注意:Variant是一种多态类型,它是子类IntVariable、DoubleVariant等的基础),第二个是C函数调用 我们知道编译时的每一条信息:参数计数是参数的数量,参数/返回类型取决于'cfunc'变量类型 // We will assume that the two following functions are defined with their correct // spe

我试图弄清楚如何创建一个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;
}
//我们假设以下两个函数都是用正确的
//专业化。
模板
变量*convertToVariant(T);
模板
T转换变量(变量*变量);
//下面的函数不完整,问题是如何转换
//将变量参数转换为C函数调用?
模板
Variant*wrapc函数(int argc,Variant**argv){
//下面是cfunc的神奇召唤,比如:
如果(argc!=mpl::count::值)
抛出std::runtime_错误(“错误参数计数”);
返回cfunc(convertFromVariant(argv[X]));
}
//示例用例:
int foo(int a、int b);
内部主(空){
int argc=2;
Variant*argv[2]={new IntVariant(5),new IntVariant(6)};
变量*res=wrapc函数(argc,argv);
IntVariant*intRes=dynamic_cast(res);
返回intRes?intRes->值:-1;
}
类变量;
模板Variant*convertToVariant(T);
模板T convertFromVariant(Variant*Variant);
模板
结构WrapCFunctionImpl{
模板
结构Impl{
typedef typename Impl::Type Type;
};
};
模板
模板
结构wrapcfonfictionimpl::Impl{
typedef Impl类型;
静态变量*运行(返回cfunc(参数…,变量**argv){
返回convertToVariant(cfunc(convertFromVariant(argv[argIndexes])…);
}
};
模板
Variant*wrapc函数(返回cfunc(参数…),Variant**argv){
返回wrapcfonfictionimpl::template Impl::Type::run(cfunc,argv);
}
int foo(int,int);
变型*f(变型**x){
返回wrapc函数(foo,x);
}
这里最大的困难是递归生成数组中的索引。可能有更简单的方法,但这是可行的。

classvariant;
模板Variant*convertToVariant(T);
模板T convertFromVariant(Variant*Variant);
模板
结构WrapCFunctionImpl{
模板
结构Impl{
typedef typename Impl::Type Type;
};
};
模板
模板
结构wrapcfonfictionimpl::Impl{
typedef Impl类型;
静态变量*运行(返回cfunc(参数…,变量**argv){
返回convertToVariant(cfunc(convertFromVariant(argv[argIndexes])…);
}
};
模板
Variant*wrapc函数(返回cfunc(参数…),Variant**argv){
返回wrapcfonfictionimpl::template Impl::Type::run(cfunc,argv);
}
int foo(int,int);
变型*f(变型**x){
返回wrapc函数(foo,x);
}
这里最大的困难是递归生成数组中的索引。可能有更简单的方法,但这是可行的。

使用,这相当简单:

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)>());
}
模板结构索引{};
模板
结构索引:索引{};
模板
结构索引:索引{};
//假设参数实际上是这样的
模板
Variant*wrapc函数(返回(*cfunc)(Args…),int argc,Variant**argv,index){
返回cfunc(convertFromVariant(argv[Is])…);
}
模板
Variant*wrapc函数(返回(*cfunc)(Args…),int argc,Variant**argv){
如果(argc!=sizeof…(Args))
抛出std::runtime_错误(“错误参数计数”);
返回wrapc函数(cfunc、argc、argv、index_gen());
}
请注意代码中的一些更改。首先,
sizeof…(Args)
生成包中的参数数。其次,我修复了函数的签名,将其作为实际参数传递给
cfunc

使用,这相当简单:

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)>());
}
模板结构索引{};
模板
结构索引:索引{};
模板
结构索引:索引{};
//假设参数实际上是这样的
模板
Variant*wrapc函数(返回(*cfunc)(Args…),int argc,Variant**argv,index){
返回cfunc(convertFromVariant(argv[Is])…);
}
模板
Variant*wrapc函数(返回(*cfunc)(Args…),int argc,Variant**argv){
如果(argc!=sizeof…(Args))
抛出std::runtime_错误(“错误参数计数”);
返回wrapc函数(cfunc、argc、argv、index_gen());
}

请注意代码中的一些更改。首先,
sizeof…(Args)
生成包中的参数数。其次,我修正了函数的签名,将
cfunc
作为实际参数传递。

出于好奇,你到底为什么想要运行时变量而不是编译时变量,例如?@ildjarn我使用运行时变量在动态语言的运行时库中保存值(如Zend引擎中的zValue).我能想到的最好的答案,我只是想问一下。:-]出于好奇,你到底为什么想要运行时变量而不是编译时变量,例如?@ildjarn我正在使用运行时变量在动态语言的运行时库中保存值(如Zend引擎中的zValue)。我能想到的最好答案是,我想我会问::-]哇,谢谢,我不知道这个把戏。我真的很喜欢C++11。。。然而,有趣的是,C++元编程仍然需要这么多的黑魔法:“@尼森:我不会真正称之为“黑魔术师”,因为这个技巧本身是相当容易理解的。您基本上生成了一组可变参数索引。此生成是通过p的递归完成的