【问题标题】:C++ - Know if a type / class is nested?C++ - 知道类型/类是否嵌套?
【发布时间】:2013-05-01 18:42:41
【问题描述】:

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

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

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) }; };

(请注意,我不关心也不(负担得起)知道 what 类型将 Type 嵌套在其中;重要的是它是否嵌套在 something em> 与否。换句话说,这个特征应该依赖于Type。)

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

【问题讨论】:

  • 这是要解决什么问题?
  • 我主要是在理论上讨论如何通过禁用嵌套在结构中的enums 的关系运算符来改进我的adaption of typesafe enums in C++03;这是我正在研究解决该问题的两种方法之一。

标签: c++ templates nested traits


【解决方案1】:

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

在这种情况下,例如:

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

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

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

is_nested&lt;my_vector&lt;int&gt;::iterator&gt;::value 应该产生什么?您可能希望结果为true

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

is_nested<int*>::value

因此,在给定相同类型T(在本例中为int*)的情况下,相同的is_nested&lt;T&gt; trait 应该会产生两个不同的结果。 is_nested&lt;&gt; 定义 value 所依据的信息无法从 T 类型本身检索 - 模板使用类型,而不是名称。

【讨论】:

  • 关于指针作为迭代器和可能出现的其他类似情况的优秀观点。那时虽然我希望编译器能够解决它,因为迭代器 type 是已知的;在这种情况下,例如,此特征将有助于确定容器类型是否具有连续存储(如果迭代器类型是原始指针,则肯定会产生false,否则可能会产生true)。
  • @LuisMachuca:不确定您所说的“解决 it”是什么意思。 “它”是什么意思?你的is_nested&lt;&gt; trait 会在输入中得到一个type,在这两种情况下都是int*。这就是is_nested&lt;&gt; 所知道的一切。在给定相同模板参数的情况下,您无法对 is_nested&lt;&gt; 进行编程以产生不同的结果。
  • ……是的,不幸的是。这意味着我将不得不放弃这种方法。
  • @LuisMachuca: 恐怕是这样 :(
  • 嗯,此时我应该问这里正确的协议是什么?问题是否标记为已回答但未解决、已全部关闭或...?
【解决方案2】:

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

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,没有嵌套。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-23
    • 1970-01-01
    • 2021-12-24
    • 2022-10-25
    • 2015-02-14
    • 2019-06-10
    • 1970-01-01
    • 2019-02-17
    相关资源
    最近更新 更多