C++:"trait" 和 "meta-function" 是同义词吗?

C++: are "trait" and "meta-function" synonymous?

或者,特质是否指的是利用元函数的特定方式?

如果它们不是同义词,请指出一些特征不是元函数的例子 元函数 特征 。一段实际工作的代码,可能在 STL 或 Boost 库中,比人为的玩具示例更受欢迎。

我想看看 C++ 编程领域的专家如何使用这些术语。不知道有没有权威的定义...

提前致谢!


澄清:我并不是在寻找 任何 特征或元函数的例子。我在日常工作中使用了数十个(如果不是数百个)。


"Venn0110". Licensed under Public Domain via Commons.

这两个词不等价。

元函数

该术语未在 C++ 标准中定义。

似乎有两个主要的竞争定义:

1) "meta-functions derive/calculate/map-to values or types (based on their arguments/parameters) at compile time", and/or

  • constexpr 功能可能包含也可能不包含在任何给定人员的 definition/conception 中;存在功能重叠,但许多提及元函数的现有文章早于或根本不讨论 constexpr 函数,因此很难知道 故意 给出的任何定义或示例是否留有余地支持或排除他们

2) "meta-functions are functions and/or classes utilising template meta-programming",具体是指一个核心代码(模板)可以被不同的参数复用,进行一些基于此的代码生成或转换

  • 元编程的最终产品不一定是编译时类型或常量 - 它可能是旨在与 运行时间值或数据一起使用的函数

对 "meta function c++"

的前 google 结果的小型调查

"metafunctions accept types and compile-time constants as parameters and return types/constants. A metafunction, contrary to its name, is a class template."

"code...executed and its result used while...compiling. ...meta-functions can compute two things: values or types"

this article 使用 "meta function" 引用 class 模板产生编译时 values/types


特质

C++ 标准没有定义 "traits",但定义了 "traits class"es:

17.3.25 [defns.traits] 特征 class

a class that encapsulates a set of types and functions necessary for class templates and function templates to manipulate objects of types for which they are instantiated [ Note: Traits classes defined in Clauses 21, 22 and 27 are character traits, which provide the character handling support needed by the string and iostream classes. —end note ]

我要补充一点,特征可以有 ,以及类型和函数 - 例如 rank 公开 ::value。特征提供 types/values 提供对参数类型本身的洞察力,或者当系统处理该类型的变量时使用该特征的系统所需的行为。

标准库的字符特征包含 运行time 功能示例:例如 X::length(p)X::find(p, n, c).

C++ 标准库中的 <type_traits> 头文件是初步了解特征可用于何种用途的好地方。

Traits 传统上是典型的(但现在 C++11 不一定提供 constexpr 函数)classes,与元函数或其他函数不同。

特征可能会告诉您参数 T 是否为常量,是否可序列化,或者在通过 TCP 传输时是否应该压缩:任何其他通用代码可能需要自定义其它处理的类型范围的行为。

有时特征将由使用它们的系统提供 - 其他时候它们可以由希望在每种类型的基础上自定义其行为的客户端代码提供。

特征可以使用参数类型的各种测试来推断事物,或者它们可以是针对特定类型的手工制作的专业化硬编码值。

这篇 ACCU 的 traits 简介](http://accu.org/index.php/journals/442) 值得一读,其中引用了 C++ 的创建者的话:

Think of a trait as a small object whose main purpose is to carry information used by another object or algorithm to determine "policy" or "implementation details". - Bjarne Stroustrup

对比 "meta function" 与 "traits"

无论您采用哪种元函数定义,标准都与实现细节有关:当函数可以被评估时,and/or是否涉及代码generation/transformation。这与特征形成对比,其中关键 concept/requirement 是它们的目的,而不是常见的 - 但远非通用 - 使用模板专业化或实例化的实现,或任何编译时间容量与 运行-时间评价。

元函数(在 C++ 的上下文中)是一种生成可在编译时使用的结果的函数。结果可以是类型(只能在编译时通过定义获得,使用部分特化等技术)或值(可以在编译时计算,使用模板参数可以是整数值,而不仅仅是类型) ).

特征本质上是一个 class(或对象),它将信息(策略约束、类型特征、实现细节)打包,供另一个 class(或对象)在编译时使用。打包的信息可以包含类型信息(例如 typedefs)或感兴趣的属性。例如,std::numeric_limits<T>(通过 <limits> 可用)是一个 "type trait",它提供有关算术类型的信息(例如 T 是整数类型吗?值集是 T可以表示bounded还是finite?是Tsigned?等)。这些信息以某种形式打包,以便元程序(即模板函数或 classes)可以在编译时使用这些信息。例如,模板元函数可能使用来自类型特征的信息来确保模板仅针对无符号整数类型进行实例化,并且如果尝试针对其他类型实例化模板则会触发编译错误。

从这个意义上说,特征是一种元函数,它在编译时提供信息供其他元函数使用。

"Meta" 是模板编程的 C++ 术语。一个明显的例子是 Boost 元编程库 (MPL)。

从这个意义上说,元函数是一个函数,其域不是对象而是 C++ 构造。因此,公共输入是类型、普通函数和其他模板。

一个简单的元函数例如 template<typename T> using Foo = Bar<T, int>,它的输入类型为 T,输出类型为 Foo<T>。微不足道,是的,但普通函数也可以是微不足道的。

特征是一个元函数,其辅域是一个常量表达式,通常是布尔值。例如。 is_foo<T>::value 显然是布尔值。从这个意义上说,最古老的特征是 sizeof(T),其密码域是 size_t.

据我所知,这些术语没有任何正式定义。所以我会提供我使用的那些。

元函数是 return 类型的模板。通常,returned 结果是一个包含名为 "type" 的成员类型的类型,因此可以通过后缀 ::type 访问它。调用元函数的示例:

using new_type = std::common_type<int, char>::type;

(参见 http://en.cppreference.com/w/cpp/types/common_type

特征是一种特殊类型的元函数,return其结果可转换为布尔值。示例:

bool ic = std::is_convertible<char, int>::type;

请注意,如今元函数结果具有成员名称 "type" 的要求已放宽,因此某些元函数的定义方式可能会删除 ::type。示例:

bool ic = std::experimental::is_convertible_v<char, int>;