C ++ - 知道类型/类是否嵌套?

时间:2013-05-01 18:42:41

标签: c++ templates nested traits

在C ++中看到许多元编程的例子,它们可以找出类的属性(例如knowing if a type is a specialization of a template),或者知道类是否包含给定的嵌套类型;但是我想知道是否有可能编写一个确定最后一个的倒数的测试或特征 - 检查给定的Type是否嵌套在classstruct中。 / p>

换句话说,我正在寻找以下伪代码的等价物:

template <typename Type> struct is_nested {
    enum { value = {__some magic__} };
};

typedef int type1;
struct Something { typedef int internal_type; };
typedef Something::internal_type type2;

//...later, likely at a different scope

is_nested< int >::value; // yields false
is_nested< std::vector<int>::iterator >::value; // yields true
is_nested< type1 >::value; // yields false
is_nested< type2 >::value; // yields true

我知道我可以使用sizeof来实现是/否测试,我认为Type是这些测试的一部分,但我无法弄清楚如何插入某种“任何测试可行类型“进入测试,以便我可以形成像Anytype::Type这样的表达式。

template 
struct is_nested
{
    typedef char yes;
    typedef struct { char u[2]; } no;

    // Herein lies the problem
    ???? static yes test( char [ sizeof(Anytype::Type) ] ) ;
    ???? static no test(...);


public:
    enum { value = sizeof(test(0)) == sizeof(char) };
};

(请注意,我并不关心(能够承担)知道将{{1>}嵌套到哪个类型;重要的是它是否嵌套在或不是。换句话说,此特征依赖于Type。)

我正在寻找C ++解决方案,无论是在C ++ 11还是C ++ 03中,但在第一种情况下,如果它是向后移植的,我会更欢迎它。

2 个答案:

答案 0 :(得分:1)

您所要求的是不可能的,但不是由于技术限制,而是因为您无法始终确定类型名称是否标识嵌套类型 - 并且模板可以使用类型而不是名字。

在这种情况下,例如:

is_nested< std::vector<int>::iterator >::value

你不知道iterator是什么。考虑这个班级my_vector

template<typename T>
struct my_vector
{
    typedef T* iterator;
    // ...
};

is_nested<my_vector<int>::iterator>::value应该得到什么?您可能希望结果为true

但是,这里嵌套的是别名,而不是类型本身:类型int*不是嵌套的。事实上,我希望您希望以下内容产生false

is_nested<int*>::value

所以这里相同的is_nested<T>特征应该产生两个不同的结果,给定相同的类型T(在这种情况下为int*)。无法从类型is_nested<>本身检索基于value应定义T的信息 - 模板可以使用类型而不是名称。

答案 1 :(得分:0)

可以检查&#34;规范类型&#34; (解析所有别名后的结果类型)使用编译器的非标准功能嵌套。

CTTI可以在编译时获取类型的名称。然后在字符串中找到:

#include <vector>
#include "ctti/type_id.hpp"

constexpr bool has_colon(const ctti::detail::string& s, size_t i) {
    return i < s.length() ? (s[i] == ':' || has_colon(s, i + 1)) : false;
}

template<typename T>
using is_nested = integral_constant<bool, has_colon(ctti::type_id<T>().name(), 0)>;

typedef int type1;
struct Something { typedef int internal_type; };
typedef Something::internal_type type2;

static_assert(!is_nested< int >::value, "");
static_assert(is_nested< std::vector<int>::iterator >::value, "");
static_assert(!is_nested< type1 >::value, "");
// static_assert(is_nested< type2 >::value, ""); // fail

第4次检查将失败,因为type2只是int,而不是嵌套。