6

在看到许多 C++ 元编程示例后,这些示例允许找出类的可能属性(例如知道一个类型是否是模板的特化),或者知道一个类是否包含给定的嵌套类型;但我想知道是否可以编写一个测试或特征来确定最后一个的倒数 - 检查给定Type是否嵌套在 a classorstruct中。

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

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

模板
结构 is_nested
{
    typedef char 是;
    typedef struct { char u[2]; } 不;

    // 问题就出在这里
    ???静态是测试(字符[sizeof(Anytype::Type)]);
    ???静态无测试(...);


上市:
    枚举 { 值 = sizeof(test(0)) == sizeof(char) };
};

(请注意,我不关心也不(负担得起)知道将嵌套什么类型Type;重要的是它是否嵌套在某些东西中。换句话说,这个特征应该依赖于Type。)

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

4

2 回答 2

1

您要问的问题是不可能的,但不是由于技术限制,而是因为您无法始终判断类型名称是否标识嵌套类型 - 模板与types一起使用,而不是名称。

在这种情况下,例如:

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>给定相同类型的情况下,相同的特征应该产生两个不同的结果Tint*在这种情况下)。无法从类型本身检索is_nested<>应定义的信息- 模板使用类型,而不是名称。valueT

于 2013-05-01T18:50:01.507 回答
1

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

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 次检查将失败,因为type2is just int,它没有嵌套。

于 2016-05-24T13:05:56.070 回答