C ++有时会在类型定义上使用后缀_type
(例如std::vector<T>::value_type
),
有时也_t
(例如std::size_t
),或没有后缀(普通类,还有像std::string
这样的类型定义std::basic_string<...>
)
关于何时使用哪个名称有什么好的约定吗?
答案 0 :(得分:13)
正如@MarcoA。答案正确指出的那样,后缀_t
主要是从C继承的(在全局命名空间中 - 为POSIX保留)。
这给我们带来了#34;没有后缀&#34;和_type
。
请注意,std
中没有以_type
* 结尾的命名空间范围名称;所有这些名称都是类和类模板的成员(或者,在正则表达式相关类型的情况下,是嵌套命名空间的一部分,它主要扮演一个类的角色)。我认为这是区别:类型本身不使用_type
后缀。
后缀_type
仅用于表示类型的成员,而且通常当它们表示某种类型时,&#34;外部&#34;到包含类。将来自矢量模板参数std::vector<T>::value_type
和std::vector<T>::size_type
的{{1}}和T
分别与Allocator
进行比较,这是&#34本征&#34;到矢量类模板。
*不完全正确,有一些这样的名字(在@jrok的评论中也有指出):std::vector<T>::iterator
,common_type
,underlying_type
,is_literal_type
, true_type
。在前三个中,false_type
实际上不是后缀,它是名称的实际部分(例如元函数,用于提供公共类型或基础类型)。对于_type
和true_type
,它确实是一个后缀(因为false_type
和true
是保留字)。我会说它是类型,表示基于类型的元编程意义上的真/假值。
答案 1 :(得分:5)
作为C遗产,_t
(过去的意思是“通过 typedef
定义”)语法已被继承(它们也是SUS/POSIX-reserved in全局命名空间)。
在C ++中添加但在原始C语言中不存在的类型(例如size_type
)不需要缩短。
请记住,据我所知,这更像是对既定惯例而非一般规则的观察。
答案 2 :(得分:2)
成员类型在C ++标准库中称为type
或something_type
。这是可读性和描述性的,添加的详细程度通常不是问题,因为用户通常不会拼出那些类型名称:大多数都用在函数签名中,然后auto
负责成员函数返回类型,在C ++ 14中,_t
类型别名负责类型特征静态类型成员。
这导致第二点:独立的非成员类型通常称为something_t
:size_t
,int64_t
,decay_t
等。 C中的遗产元素,但C ++的不断发展保持了惯例。据推测,简洁性在这里仍然是一种有用的品质,因为预计这些类型一般都会被列出。
最后,以上所有内容仅适用于我可能称之为&#34;泛型类型派生&#34;:给定X
,给我一些相关类型X::value_type
,或给定一个整数,给出我是64位的变种。因此,约定仅限于常见的词汇类型名称。您的实际业务逻辑的类名(包括std::string
)可能不保证这样的命名模式,我不认为很多人想要破坏每个类型名。
如果愿意,_t
和_type
命名约定主要适用于标准库和标准库样式的某些方面,但您不需要将它们视为某种通用任务。
答案 3 :(得分:0)
我的答案仅与名称空间在命名空间(不是std
中)有关。
_type
这就是问题:标识符foo_type
可以解释为
foo
的事物的类型标识符”(例如size_type overall_size = v1.size() + v2.size();
)employment_type my_employment_type = FIXED_TERM;
)当您使用键入定义的枚举时,我认为您倾向于第二种解释-否则,您将如何称呼您的枚举类型?
不使用后缀的常见厌恶之处在于看到标识符foo
令人困惑:它是变量,还是特定的foo?还是foos的类型? ...幸运的是,当您在命名空间中时,这不是问题:my_ns::foo
显然是一种类型-您不会弄错它;所以在那里不需要前缀。
PS-我采用的做法是在类中给我的typedef加后缀_type
(pointer_type
,value_type
,reference_type
等。)但在这一点上,我不知何故违反传统。
现在,您可以查询-如果您在类中有枚举,该怎么办?好吧,我尽量避免这种情况,并将枚举放在周围的名称空间中。