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

时间:2015-09-09 04:59:49

标签: c++ template-meta-programming

或者, trait 可能是指使用元功能的特定方式吗?

如果他们是同义词,请指出 traits 的一些示例,这些 traits 不是元功能元函数不是 traits 。一个实际工作的代码,可能在STL或Boost库中,将被欣赏,而不是一个人为的玩具示例。

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

提前致谢!

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

Venn0110.svg
Venn0110”。通过Commons在公共域下获得许可。

4 个答案:

答案 0 :(得分:4)

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

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

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

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

答案 1 :(得分:3)

这些条款不相同。

元函数

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

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

1)“元函数派生/计算/映射到值或类型(基于它们的参数/参数) 在编译时 ”,和/或

  • constexpr函数可能包含也可能不包含在任何给定人员的定义/概念中;虽然存在功能上的重叠,但是很多现有的提及元函数的文字都在讨论constexpr函数之前或者之前也没有讨论::value函数,因此很难知道故意给出的任何定义或示例是否留有空间或排除它们

2)“元函数是利用 模板元编程 ”的函数和/或类,具体意味着代码核心(模板)可以重用对于不同的参数,执行一些代码生成或基于此的转换

  • 元编程的最终产品不一定是编译时类型或常量 - 它可能是一个用于运行时值或数据的函数

对“meta function c ++”

的热门谷歌搜索结果的一项小调查

"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使用“元函数”来引用类模板,产生编译时值/类型

性状

C ++标准没有定义“traits”,但确实定义了“traits class”es:

17.3.25 [defns.traits] traits class

  

一个类,它封装了类模板和函数模板所需的一组类型和函数,以操作实例化它们的类型的对象   [注意:第21,22和27条中定义的Traits类是字符特征,它提供字符串和iostream类所需的字符处理支持。 - 后注]

我补充说,特征可以包含,以及类型和函数 - 例如rank公开X::length(p)。 Traits提供类型/值,提供对参数类型本身的洞察,或当系统处理该类型的变量时使用特征所需的系统行为。

标准库的角色特征包含运行时功能的示例:例如X::find(p, n, c)constexpr

C ++标准库中的<type_traits>标题是初步了解可以使用哪些特性的好地方。

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

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

有时候特征会由使用它们的系统提供 - 有时它们可​​以由希望按类型自定义其行为的客户端代码提供。

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

ACCU对特征的介绍](http://accu.org/index.php/journals/442)值得一读,并包含了C ++创建者的这句话:

  

将特征视为一个小对象,其主要目的是携带另一个对象或算法使用的信息来确定“策略”或“实现细节”。 - Bjarne Stroustrup

将“元功能”与“特征”对比

无论您采用哪种元函数定义,标准都与实现细节有关:何时可以评估函数,和/或是否涉及代码生成/转换。这与特征形成鲜明对比,其中关键概念/要求是它们的目的,而不是通用 - 但远非普遍 - 使用模板特化或实例化的实现,或任何编译时间与运行时评估的容量。 / p>

答案 2 :(得分:2)

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

特征本质上是一个类(或对象),它在编译时打包信息(策略约束,类型特征,实现细节)以供另一个类(或对象)使用。打包的信息可以包括类型信息(例如typedef s)或感兴趣的属性。例如,std::numeric_limits<T>(可通过<limits>获得)是&#34;类型特征&#34;它提供了有关算术类型的信息(例如,T是一个整数类型?是一组值T可以表示有界还是有限?是T signed?等等。信息以表格形式打包,以便元程序(即模板函数或类)可以在编译时使用该信息。例如,模板元函数可能使用来自类型特征的信息来确保模板仅针对无符号整数类型进行实例化,并在尝试实例化其他类型的模板时触发编译错误。

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

答案 3 :(得分:0)

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

元功能是返回类型的模板。通常,返回的结果是一个包含名为&#34; type&#34;的成员类型的类型。所以可以通过后缀:: type访问它。调用元函数的示例:

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

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

特征将是特殊类型的元函数,它返回可转换为bool的结果。例如:

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

请注意,现在,要求元函数结果具有成员名称&#34; type&#34;因此可以放宽一些元函数,以便可以删除:: type。例如:

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