1

我想创建一个模板来检查类类型是否为原始类型(int、char、float、float*** 等)。这样做的原因是为了防止另一个模板尝试扩展原语并导致编译时错误。到目前为止,我有一些类似的东西:

#include <typeinfo>
template<typename T>
struct is_primitive{
   const static bool value=std::is_fundamental<T>::value;
};

显然,这只是现在转发 is_fundamental 的结果。我想添加 remove_pointer、remove_reference 等...以去除输入类的所有这些额外修饰符。 使 T 尽可能裸露的所有必要删除是什么?

或者,类似以下的解决方案同样出色:

template<typename T>
struct is_inheritable{
   const static bool value=???;
};

但我很确定不可继承类的集合等于原始类的集合。

4

3 回答 3

5

这听起来像你想要std::is_class<T>的。只能从类类型继承。这是描述 C++11 类型分类特征的图表:这里 http://howardhinnant.github.io/TypeHiearchy.pdf

http://howardhinnant.github.io/TypeHiarchy.pdf

于 2013-03-22T00:12:20.807 回答
1

我建议您尝试专注于检测在您的情况下需要可继承的类型的属性,而不是考虑检测那些不可继承的类型。运气好的话,您的类需要基类中可以检查的其他属性,因为您的派生类将需要调用基类的至少一个构造函数。

尝试使用is_constructible或一些相关的类型特征:

// check that T::T(std::string,int); exists:
std::is_constructible< T, std::string, int >::value

// or these direct traits for the usual suspects...
std::is_default_constructible< T >::value
std::is_copy_constructible< T >::value
std::is_move_constructible< T >::value

对于您的其他问题,如果在上述之后仍然相关,请检查std::decay并将其与其他特征结合以根据需要剥离类型:

template< typename T, typename = void >
struct strip
{
     typedef T type;
};

template< typename T >
struct strip< T, typename std::enable_if<
  !std::is_same< typename std::decay< T >::type, T >::value
>::type >
    : strip< typename std::decay< T >::type >
{
};

template< typename T >
struct strip< T, typename std::enable_if<
  std::rank< T >::value != 0
>::type >
    : strip< typename std::remove_all_extents< T >::type >
{
};

template< typename T >
struct strip< T, typename std::enable_if< std::is_pointer< T >::value >::type >
    : strip< typename std::remove_pointer< T >::type >
{
};

typedef const int*(&Test)[42];
static_assert( std::is_same< typename strip< Test >::type, int >::value, "" );

但是当然,您需要弄清楚您的情况到底适合什么。

于 2013-03-21T07:56:43.300 回答
0
template <typename T>
struct remove_all { typedef typename std::remove_cv<T>::type type; };
template <typename T>
struct remove_all<T*> { typedef typename remove_all<T>::type type; };
template <typename T>
struct remove_all<T&> { typedef typename remove_all<T>::type type; };
template <typename T>
struct remove_all<T&&> { typedef typename remove_all<T>::type type; };

template<typename T>
struct is_primitive{
    typedef typename remove_all<T>::type TF;
    const static bool value=std::is_fundamental<TF>::value;
};

在这里找到 remove_all 结构讨论。

于 2013-03-21T01:41:05.837 回答