Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.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++;模板元编程:模板类型上的编译时条件运算符_C++_Templates_Reflection_Metaprogramming_Variant - Fatal编程技术网

C++ C++;模板元编程:模板类型上的编译时条件运算符

C++ C++;模板元编程:模板类型上的编译时条件运算符,c++,templates,reflection,metaprogramming,variant,C++,Templates,Reflection,Metaprogramming,Variant,我使用模板元编程来创建变量和函子(泛型函子)数据类型。我有一个有趣的问题,需要以特定的方式处理特定参数类型的参数。理想情况下,我希望使用某种编译时条件运算符来处理给定参数,如果条件满足,则使用方法a;如果条件失败,则使用方法B 高级问题摘要: 我需要通过以下方式向函数指针上的调用传递一个变量 变量的内部值,或者根据预期的参数类型是否为变量类型,将变量本身传递给调用 详细信息: 调用函子时,使用变量数组模拟函数参数。下面是我的函子的一个重载构造函数的示例: Variant operator()

我使用模板元编程来创建变量和函子(泛型函子)数据类型。我有一个有趣的问题,需要以特定的方式处理特定参数类型的参数。理想情况下,我希望使用某种编译时条件运算符来处理给定参数,如果条件满足,则使用方法a;如果条件失败,则使用方法B

高级问题摘要:

  • 我需要通过以下方式向函数指针上的调用传递一个变量 变量的内部值,或者根据预期的参数类型是否为变量类型,将变量本身传递给调用
详细信息

调用函子时,使用变量数组模拟函数参数。下面是我的函子的一个重载构造函数的示例:

Variant operator()( Variant arg0, Variant arg1, Variant arg2 );
变量可以用我传递给它的任何类型的数据构造。在我开始这段代码之前,这一切都很好(对于需要3个参数的签名,这是一个特定的functor call helper类):

模板
变型静态FNCALL3(多NPTR fn、变型和arg0、变型和arg1、变型和arg2)
{
返回reinterpret_cast(fn.StaticFn)(arg0.GetValue(),arg1.GetValue(),arg2.GetValue());
}
每个函子存储一个函数指针,函数指针存储在名为multinptr(多函数指针)的并集中。调用函子时,将联合类型转换为相应的签名类型,如上所示。传递给函子的每个变量都会通过GetValue方法转换为变量中保存的值。这意味着我正在将调用期间传递给函子的每个变量的内部数据转换为各自的值。要转换为的值的类型是通过将模板化StaticFnCall与multinptr的签名相匹配而推导出来的

下面是GetValue的实现:

template <typename TYPE>
const TYPE& VariantBase::GetValue( void ) const
{
  return *reinterpret_cast<TYPE *>(data);
}
模板
常量类型&VariantBase::GetValue(void)常量
{
返回*重新解释(数据);
}
问题是,我试图将函数签名包装在一个函子中,该函子将变量作为其参数类型之一。只要在调用函子时将变量传递给接受变量的参数,就可以了。但是,我需要将一个任意类型传递给使用变量的参数。然后使用GetValue将任意类型转换为Variant*,这会导致该任意类型的数据被逐字解释为变量,而我希望使用变量的构造函数创建一个变量,以传递给在Functor内调用的函数指针

我一直在尝试想出一种方法,直接将值传递给StaticFnCall的函数指针,而不是在相应的模板类型为变量时使用GetValue。我已经查找了std::enable_if和sfinae,但我正在努力找到一个解决方案。下面是我试图实现的伪代码示例:

template <typename R, typename T0, typename T1, typename T2>
Variant StaticFnCall3( MultiFnPtr fn, Variant& arg0, Variant& arg1, Variant& arg2 )
{
  return reinterpret_cast<typename VoidToType<R>::type(*)(T0, T1, T2)>(fn.StaticFn)( (IF_IS_VARIANT) ? arg0 : arg0.GetValue<T0>( ), (IF_IS_VARIANT) ? arg1 : arg1.GetValue<T1>( ), (IF_IS_VARIANT) ? arg2 : arg2.GetValue<T2>( ) );
}
模板
变型静态FNCALL3(多NPTR fn、变型和arg0、变型和arg1、变型和arg2)
{
返回reinterpret_cast(fn.StaticFn)((如果_是变量)?arg0:arg0.GetValue(),(如果_是变量)?arg1:arg1.GetValue(),(如果_是变量)?arg2:arg2.GetValue());
}
编辑

因此,我发现我可以使用模板化全局函数,并使用模板专门化以两种方式之一处理参数。但是,这不是编译时解决方案,因为全局函数将导致分支,除非函数是内联的

template<typename T>
const T ArgHandle( const RefVariant& arg )
{
  return arg.GetValue<T>( );
}

template<>
const Variant ArgHandle<Variant>( const RefVariant& arg )
{
  return Variant( arg );
}
模板
常量ArgHandle(常量RefVariant&arg)
{
返回arg.GetValue();
}
模板
常量变量ArgHandle(常量引用变量和arg)
{
返回变量(arg);
}
由于函数ArgHandle在编译时具有重载解析,我想可能有某种方法可以在不调用函数的情况下实现我想要的行为。使用:

#define ARG( NUM ) \
  ArgHandle<T##NUM>( arg##NUM )

template <typename R, typename T0, typename T1, typename T2>
Variant StaticFnCall3( MultiFnPtr fn, RefVariant& arg0, RefVariant& arg1, RefVariant& arg2 )
{
  return reinterpret_cast<typename VoidToType<R>::type(*)(T0, T1, T2)>(fn.StaticFn)( ARG( 0 ), ARG( 1 ), ARG( 2 ) ) );
}
#定义ARG(NUM)\
ArgHandle(arg##NUM)
模板
变量静态FNCALL3(多输入变量fn、参考变量和arg0、参考变量和arg1、参考变量和arg2)
{
返回reinterpret_cast(fn.StaticFn)(ARG(0)、ARG(1)、ARG(2));
}

我不明白你为什么不在这部分问题之后停下来:

template <typename TYPE>
const TYPE& VariantBase::GetValue( void ) const
{
  return *reinterpret_cast<TYPE *>(data);
}
就这样吧。有些东西不适合这个吗?在您的问题后面,您似乎一直在讨论这个解决方案,但到那时,您已经引入了毫无意义的
ArgHandle
函数、宏和助手函数,这一切都是一团糟


就我个人而言,我会完全放弃
GetValue
函数,只提供隐式类型转换运算符,这样您就可以编写
fn(arg0,arg1,arg2)
。但我想这取决于代码的其余部分是什么样子。

这个小函数很可能会内联,您不必担心对ArgHandle()的函数调用,我将尝试模板专门化!谢谢你的主意。一旦我搞砸了,我会再打给你的。
template <typename TYPE>
const TYPE& VariantBase::GetValue( void ) const
{
  return *reinterpret_cast<TYPE *>(data);
}
template <>
const VariantBase& VariantBase::GetValue<VariantBase>( void ) const
{
  return *this;
}