【问题标题】:What kind of "Traits" are used/defined in the C++0x Standard在 C++0x 标准中使用/定义了什么样的“特征”
【发布时间】:2011-10-06 19:32:23
【问题描述】:

C++ 中的特征封装了一系列操作,这些操作允许算法或数据结构使用其实例化的类型进行操作。 char_traits 是分组 string 和文件所需函数的示例。

但并非所有特质的名字中都有“特质”,对吧? numeric_limits 浮现在脑海中。这也是“特质”吗?即使没有“特质”这个名字?

那么,还有其他可以/应该被视为“特征”的模板吗?除了我找到的示例之外:

  • allocator_traits如何获取内存
  • pointer_traits如何间接访问对象
  • type_traits元编程
  • char_taits 用于符号序列
  • iterator_traits 如何前进、后退和到达元素
  • regex_traits 用于...正则表达式。

我想,我也想问的是,特性是否有一个纯粹的定义

我特别不确定的一些事情是:

  • numeric_limits上面提到了
  • <chrono>s 自定义“特征”,[20.11.4],即duration_values
  • 哈希呢?函子hash<> 可以被认为是一个特征吗?
  • 如果是这样,难道不是所有需求都是“特征”,例如“CopyAssignable”等?
  • 那么,被抛弃的“概念”是最终的“特征”——定义吗?

更新:究竟是什么让一个特质成为特质这个问题在细节上似乎有点争议。也许可以回答另一个问题:是否有一个完整的列表,哪些类 trait-like 类是 C++0x 新的,哪些已经在 C++03 中? 也许有人知道到某个地方的链接?

【问题讨论】:

  • 这应该是 CW,因为有许多可能的“正确”答案。我猜那个选项不再存在?无论如何,iostream 方面是 trait 的一种形式。
  • 我不认为hash<> 被认为是一个特征类,因为它不仅仅提供关于类的编译时信息。这个定义怎么样:“没有非静态成员的模板类,其静态成员仅依赖于模板参数。”
  • 我会说numeric_limits 严格来说并不是一个特征类,因为它的值并不都是编译时静态常量或constexpr——你有像max() 这样的东西是一个运行时值。
  • @Kerrek SB:char_traits 也不是严格的编译时:lengthcompare 也必须在运行时进行评估。顾名思义,它被认为是一个 trait 类。
  • 我认为numeric_limits 是一个完全有效的特征类。它没有状态,只是提供有关类型的信息。它的一些信息以静态函数的形式存在这一事实并没有使它不再是一个特征类,IMO

标签: c++ c++11 traits typetraits


【解决方案1】:

这是一个按标准划分的特征列表。我很容易忽略一些。

新的 C++11 特征:

is_error_code_enum
is_error_condition_enum
pointer_traits
allocator_traits
Just about everything in <type_traits>
treat_as_floating_point
duration_values
uses_allocator
regex_traits

C++98/03 特征:

numeric_limits
char_traits
iterator_traits

【讨论】:

  • 这是最有帮助的!仅凭您的清单,我可能就可以推断出委员会成员中(一些?全部?)认为的特征。我特别不确定is_error_..._enums。我想我至少会错过treat_as_floating_point——我将不得不对此进行调查。非常感谢。
【解决方案2】:

  • *numeric_limits* 绝对代表数字类型的一组特征。
  • “CopyAssignable”等所有要求确实是特征参见this paper on traits

    对于其他我无法评论,但如有疑问:

    把特质想象成一个主要目的是携带的小物体 另一个对象或算法用来确定“策略”的信息 或“实施细节”。 - Bjarne Stroustrup

    更新:只是为霍华德提供的广泛列表做出我的小贡献:

  • 与时间相关的特征
  • 正则表达式特征

我错误地认为,TR1 中的 type traitsregex traits 在技术上并不是 C++0x 中新特征的一部分(即使类型特征已被新的即将发布的标准大大扩展)。 请参阅霍华德对此的评论和澄清。

【讨论】:

  • 特征就是策略?嗯,这也是 Alexandrescu 的观点吗?
  • 我认为特征是策略类的一个特例。 Alexandrescu 在他的书中将它们作为一种通用编程技术提到“特征是一种通用编程技术,它允许基于类型做出编译时决策,就像您根据值做出运行时决策一样”,但他没有明确提及关于特质是政策。
  • 我将它们分开的方式是说特征是无状态的,并且只是为您提供有关类型的信息。一个策略类可能有状态,因此您可以对同一类型有不同的策略。此外,特征往往是非常小的“原始”类型、值和函数(例如value_typemax()),其中策略也可能定义更大的复合操作。
  • TR1 不规范。这意味着它不是一个标准。这只是一份非规范性文件,上面写着“我们对这些东西感兴趣”。话虽如此,认为它是规范性的是一个常见的错误。甚至 C++ 委员会的人有时也会犯这种错误。
  • @Howard Hinnant 我当然没有意识到这一点。感谢您清除它。更新了答案。
【解决方案3】:

(类型)特征是泛型编程中的简单元函数。它采用一种类型并返回一组值、函数和描述该类型某些方面的元函数。

这意味着特征是 C++ 类模板。例如,std::forward_iterator_tag 等迭代器基类不是特征。

注意事项 - 特征中的某些值本质上可能是布尔值。由于 C++ 模板限制,特征值不能是浮点类型。但是,trait 也可以包含函数,并且这些函数对返回类型没有限制。

纯特征类只包含静态成员;没有简单的相关实例数据。因此,它们也不包含构造函数。这种“纯”的区别使我们能够将像 std::vector&lt;T&gt; 这样的类描述为非纯 trait 类:实际上,它们是它们自己的 trait 类。

【讨论】:

    【解决方案4】:

    我真正喜欢与新的枚举类类型一起使用的是

    underlying_type::type 为您提供枚举类的存储说明符的类型

    enum class My_Enum : unsigned int { ... }
    
    underlying_type<My_Enum>::type -> unsigned int
    

    在枚举转换和序列化中非常有用。

    【讨论】:

    • 如果你有更具体的例子,我想看看。
    • 代码没有正确显示,因为我忘记了代码标签。我也不确定您还需要什么示例。任何时候你使用这样的枚举,你都可以使用它来获取底层类型。这也可以用于 enum_cast 将枚举类从/转换为整数。
    • 啊,我明白了。我不知道,因为我还没有使用新的enum classes。但是那个特征示例 非常有用。谢谢。 +1。
    猜你喜欢
    • 2017-08-23
    • 1970-01-01
    • 1970-01-01
    • 2010-10-04
    • 2020-10-17
    • 2011-06-07
    • 1970-01-01
    • 2010-09-21
    • 2022-01-24
    相关资源
    最近更新 更多