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++_Templates_Boost_Eigen_Boost Mpl - Fatal编程技术网

C++ 基于模板参数的条件编译时类型映射

C++ 基于模板参数的条件编译时类型映射,c++,templates,boost,eigen,boost-mpl,C++,Templates,Boost,Eigen,Boost Mpl,如何在编译时检查模板参数是否具有特定的枚举,如果为真,则获取该枚举值 我正在为模板参数T寻找类似的东西,它可能(也可能不)有枚举类型需要对齐: compile_time_if (T has NeedToAlign) { // only then compile the following EIGEN_MAKE_ALIGNED_OPERATOR_IF(typename T::NeedToAlign) } 请继续阅读以了解我的实际问题: 因此,我有一个名为Payload的类,它定义了一个enu

如何在编译时检查模板参数是否具有特定的枚举,如果为真,则获取该枚举值

我正在为模板参数
T
寻找类似的东西,它可能(也可能不)有枚举类型
需要对齐

compile_time_if (T has NeedToAlign) {
 // only then compile the following
 EIGEN_MAKE_ALIGNED_OPERATOR_IF(typename T::NeedToAlign)
}
请继续阅读以了解我的实际问题:

因此,我有一个名为
Payload
的类,它定义了一个enum
NeedsToAlign
,如下所示:

struct Payload<int N> {
 typedef Eigen::Matrix<float, N, 1> DataType;
 DataType data;

  enum {
    NeedToAlign = (sizeof(DataType)%16)==0,  ///< Check for alignement need
  };
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(EigenNeedsToAlign)
};
template<typename T, class Enable = void>
class EigenAllocatorHelper {
};

BOOST_MPL_HAS_XXX_TRAIT_DEF(NeedsToAlignMPL)

template< typename T >
class EigenAllocatorHelper< T, typename boost::enable_if< has_NeedsToAlignMPL<T> >::type > {
public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(typename T::NeedsToAlign);
};
注:如果(typename T::NeedToAlign)
我不能简单地使用
EIGEN\u MAKE\u ALIGNED\u OPERATOR\u,因为我希望
class A
也使用say T=int进行编译

是否有针对这些问题的Boost MPL解决方案?这就是我到目前为止所能想到的:

typedef typename boost::mpl::if_< 
        has_EigenNeedsToAlign<Payload>,
        typename Payload::NeedToAlign,
        boost::mpl::int_< 0 >
                                >::type result;
 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(result::value);
其中,
eignallocatorhelper
通过部分专门化注入适当的行为(如下所示):

模板
类特征分配器帮助器{
};
BOOST\u MPL\u具有XXX\u TRAIT\u DEF(需要对齐MPL)
模板
类EigenAllocatorHelper:type>{
公众:
特征值\使\对齐\运算符\新\如果(类型名T::NeedsToAlign);
};
此外,我还必须使用
typedef boost::mpl::int_uu2;NeedToAlignMPL
因为当我使用简单枚举时,mpl已经不起作用了


这个解决方案在我看来还可以,事实上我也可以在其他地方重用这个
eignallocatorhelper
类。但是如果有更好的MPL magic不需要此功能,请告诉我。

我目前正在使用以下解决方案:

#include <boost/utility/enable_if.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/and.hpp>

//! The macro is used for enable_if if T is an Eigen Type
#define ENABLE_IF_EIGEN_TYPE(T)\
    typename boost::enable_if< is_eigen_type<T> >::type

/** The macro enables Eigen new() when required. T can be any type
 *
 * Example Usage:
 *  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_REQUIRED(Eigen::Vector2d) will enable Eigen's new()
 *  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_REQUIRED(Eigen::Vector3d) will NOT
 *  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_REQUIRED(int) will NOT
 */
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_REQUIRED(T)\
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(requires_eigen_new_allign<T>::value)

namespace detail {
BOOST_MPL_HAS_XXX_TRAIT_DEF(Scalar)
BOOST_MPL_HAS_XXX_TRAIT_DEF(Index)
BOOST_MPL_HAS_XXX_TRAIT_DEF(StorageKind)
}

/**
 * Traits for checking if T is indeed an Eigen Type
 * @tparam T any Type
 *
 * Example Usage:
 * is_eigen_type<int>::value // evaluates to false
 * is_eigen_type<int>::type // evaluates to false_type
 * is_eigen_type<Eigen::Vector2d>::value // evaluates to true
 * is_eigen_type<Eigen::Vector2d>::type // true_type
 */
template<typename T>
struct is_eigen_type:
    boost::mpl::and_<
      detail::has_Scalar<T>,
      detail::has_Index<T>,
      detail::has_StorageKind<T> > {
};


template<class T, class Enable = void>
struct requires_eigen_new_allign {
  static const bool value = false;
};

template<class T>
struct requires_eigen_new_allign<T, ENABLE_IF_EIGEN_TYPE(T)> {
  typedef typename T::Scalar Scalar;
  static const bool value = (((T::SizeAtCompileTime) != Eigen::Dynamic)
      && ((sizeof(Scalar) * (T::SizeAtCompileTime)) % 16 == 0));
};
#包括
#包括
#包括
//! 如果T是本征类型,则宏用于启用_
#定义ENABLE_IF_特征类型(T)\
typename boost::如果:type,则启用
/**需要时,宏将启用Eigen new()。T可以是任何类型
*
*用法示例:
*如果需要,EIGEN_MAKE_ALIGNED_OPERATOR_NEW_(EIGEN::Vector2d)将启用EIGEN的NEW()
*如果需要,本征值使对齐运算符新(本征值::矢量3D)将不会
*如果需要(int),则本征值\使\对齐\运算符\新\将不会
*/
#如果需要,定义特征值使对齐运算符新(T)\
本征值\u使\u对齐\u运算符\u新建\u IF(需要\u本征值\u新建\u allign::value)
名称空间详细信息{
BOOST\u MPL\u具有XXX\u TRAIT\u DEF(标量)
BOOST_MPL_有_XXX_TRAIT_DEF(索引)
BOOST_MPL_有_XXX_TRAIT_DEF(StorageKind)
}
/**
*检查T是否确实是特征类型的特征
*@tparam T任何类型
*
*用法示例:
*值//的计算结果为false
*is_eigen_type::type//计算结果为false_type
*值//的计算结果是否为真
*是本征类型::类型//真类型
*/
模板
结构为特征类型:
boost::mpl::and_<
细节::具有_标量,
详细信息::有_索引,
详细信息::has_StorageKind>{
};
模板
结构需要_eigen _new _allign{
静态常量布尔值=假;
};
模板
结构需要_eigen _new _allign{
typedef typename T::标量;
静态常量布尔值=((T::SizeAtCompileTime)!=特征值::动态)
&&((sizeof(标量)*(T::SizeAtCompileTime))%16==0));
};

宏做什么?它基本上定义了两个函数,如new()。还有一个解释
template<typename T, class Enable = void>
class EigenAllocatorHelper {
};

BOOST_MPL_HAS_XXX_TRAIT_DEF(NeedsToAlignMPL)

template< typename T >
class EigenAllocatorHelper< T, typename boost::enable_if< has_NeedsToAlignMPL<T> >::type > {
public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(typename T::NeedsToAlign);
};
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/and.hpp>

//! The macro is used for enable_if if T is an Eigen Type
#define ENABLE_IF_EIGEN_TYPE(T)\
    typename boost::enable_if< is_eigen_type<T> >::type

/** The macro enables Eigen new() when required. T can be any type
 *
 * Example Usage:
 *  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_REQUIRED(Eigen::Vector2d) will enable Eigen's new()
 *  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_REQUIRED(Eigen::Vector3d) will NOT
 *  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_REQUIRED(int) will NOT
 */
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_REQUIRED(T)\
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(requires_eigen_new_allign<T>::value)

namespace detail {
BOOST_MPL_HAS_XXX_TRAIT_DEF(Scalar)
BOOST_MPL_HAS_XXX_TRAIT_DEF(Index)
BOOST_MPL_HAS_XXX_TRAIT_DEF(StorageKind)
}

/**
 * Traits for checking if T is indeed an Eigen Type
 * @tparam T any Type
 *
 * Example Usage:
 * is_eigen_type<int>::value // evaluates to false
 * is_eigen_type<int>::type // evaluates to false_type
 * is_eigen_type<Eigen::Vector2d>::value // evaluates to true
 * is_eigen_type<Eigen::Vector2d>::type // true_type
 */
template<typename T>
struct is_eigen_type:
    boost::mpl::and_<
      detail::has_Scalar<T>,
      detail::has_Index<T>,
      detail::has_StorageKind<T> > {
};


template<class T, class Enable = void>
struct requires_eigen_new_allign {
  static const bool value = false;
};

template<class T>
struct requires_eigen_new_allign<T, ENABLE_IF_EIGEN_TYPE(T)> {
  typedef typename T::Scalar Scalar;
  static const bool value = (((T::SizeAtCompileTime) != Eigen::Dynamic)
      && ((sizeof(Scalar) * (T::SizeAtCompileTime)) % 16 == 0));
};