在C++中,“cv-unqualified”是什么意思?

83
关于主题。我在最近提出的一个问题中看到了这个术语,显然这是一个很常见的术语,但我在Stack Overflow上找不到任何相关信息。

@LihO:根据我对stackoverflow的了解,复制粘贴不是回答问题的首选方法。通常需要提供非常详细的答案,并具有对规范非常具体的引用。 - Stefano Borini
2
@StefanoBorini:从谷歌搜索cv限定符的第二个结果(http://en.cppreference.com/w/cpp/language/cv)非常清晰和详尽,根本不是什么糟糕的论坛。 - Antoine
26
@Antoine: 有趣的是,人们仍然假定他们在Google中找到的东西就是别人在Google中找到的东西。 搜索结果根据您的传统浏览行为进行定制。 那不是我的第二个结果。 甚至不在第一页。 实际上,我大多数情况下得到的是不合格的工作简历公告。(可能是因为我六个月前在搜索工作) - Stefano Borini
6个回答

74

有基本类型和复合类型。基本类型包括算术类型、voidstd::nullptr_t。复合类型包括数组、函数、指针、引用、类、联合、枚举和非静态成员指针。

未加cv限定的类型是上述所有类型中的任意一种。

对于任何未加const或volatile限定的类型,都有三种相应的cv限定类型:

  • const限定 - 具有const cv限定符
  • volatile限定 - 具有volatile cv限定符
  • const-volatile限定 - 同时具有constvolatile cv限定符

但需要注意的是,应用于数组类型的cv限定符实际上适用于其元素。

带cv限定符和不带cv限定符的类型是不同的。即int是与const int不同的类型。


9
哇,我不明白为什么它被称为“cv-unqualified”?在介绍它是什么之前先告诉我们“它的含义”会更好。当然,我现在知道cv代表const和volatile。 - Chan Kim
1
为什么要使用指针、数组和非静态成员指针?难道后者不包含在前者中吗?还是我漏掉了什么? - Enlico
1
第一和第二段应该被删除吗?如果我们只是说“类型可以是cv-qualified和cv-unqualified”,那有什么区别呢? - uvsmtid
"应用于数组类型的cv限定符将应用于其元素,这与Java等语言有很大的不同,因为它们应用于变量本身而不是元素!cppreference还注意到了这种设计决策:"数组类型被认为具有与其元素类型相同的cv限定符。" - Rogue

69

如果类型没有任何cv限定符,则为“cv-unqualified”类型。cv限定符可以是constvolatile


23

CV代表着const和volatile(较少用到mutable),是用来修饰类型的两个属性。在C++11中,您可以使用std::remove_const等函数来操作它们。

优秀的cppreference网站为您提供更多信息。

回答您的问题,cv-unqualified类型要么没有cv限定符,要么被剥离了它们。例如,int是const volatile int的cv-unqualified部分。

std::remove_cv<T> ::type是T的cv-unqualified部分。


我做了,但它不在这里。我想要它在这里。 - Stefano Borini
但事实上是这样的!例如,这个问题就是关于同一主题的,但发布者表明他已经做了一些研究来理解一些基础知识,但仍然对某些具体点感到困惑。我相信这正是这个网站的精神所在。 - Antoine
8
这并不是。问题的标题没有传达其内容。我希望任何有类似疑问的人可以在谷歌上搜索“什么是CV未经审核”,并找到这个问题,其中明确解释了这个问题。另外,我认为Stackoverflow社区对于看似简单但合理的问题的这种鲨鱼式行为真的很讨厌,如果有替代方案的话,我早就换了。冷静点,人们。 - Stefano Borini
@StefanoBorini 我只是想提一下,搜索“cv unqualified C++”让我找到了这里作为第一个结果。非常感谢您在此努力,使其成为最高的搜索结果。再次感谢! - rayryeng

13
cv-unqualified type 是指没有被任何 cv-qualifiers 指定的类型。这些定义了类型的两个基本属性:constnessvolatility。 参见 C++03 3.9.3 CV-qualifiers §1:

在3.9.1和3.9.2中提到的类型是 cv-unqualified type。每种类型都有三个相应的带有cv限定符的版本:

  • 一个 const-qualified 版本,
  • 一个 volatile-qualified 版本,以及
  • 一个 const-volatile-qualified 版本。

对象类型(1.8)的术语包括创建对象时指定的cv限定符。

在 decl-specifier-seq 中存在 const 说明符,则声明一个 const-qualified 对象类型的对象;此类对象称为 const object

在 decl-specifier-seq 中存在 volatile 说明符,则声明一个 volatile-qualified 对象类型的对象;此类对象称为 volatile object

在 decl-specifier-seq 中存在两个 cv 限定符,则声明一个 const-volatile-qualified 对象类型的对象;此类对象称为 const volatile object


5
通常情况下,“去除任何cv-qualifier”意味着“相同类型的内容”,因此(例如)void volatile * const x的非cv限定版本将是void *x
注意,这里我要从指针本身和它所指向的内容中去除cv限定符。在大多数情况下,“cv-unqualified”只会指一个对象,因此指针本身的无cv限定版本仍然是void volatile *x,而它所指向的内容的无cv限定版本将是void *const x

4

我认为第一步是了解可能的类型和CV的含义:

const 和 volatile 出现在任何类型说明符中,包括声明语法的 decl-specifier-seq,用于指定所声明的对象或所命名类型的常量性或易变性。

const - 定义类型是常量。

volatile - 定义类型是易变的。

说明

对于除函数类型或引用类型之外的任何类型 T(包括不完全类型),C++ 类型系统中还有三种更具体的类型:const 限定的 T、volatile 限定的 T 和 const-volatile 限定的 T。

注意:数组类型被视为具有与其元素类型相同的 CV 限定。当对象首次创建时,CV 限定符(可以是声明或 type-id 中的 decl-specifier-seq 或 declarator 的一部分)确定对象的常量性或易变性,如下所示:

const 对象 - 类型为 const 限定或 const 对象的非可变子对象。这样的对象无法修改:直接尝试修改会导致编译时错误,通过引用或指向非 const 类型的指针间接地修改 const 对象会导致未定义行为。

volatile 对象 - 类型为 volatile 限定或 volatile 对象的子对象,或 const-volatile 对象的可变子对象。通过 volatile 限定类型的 glvalue 表达式进行的每个访问(读取或写入操作、成员函数调用等)都被视为优化目的的可见副作用(也就是说,在单个执行线程内,volatile 访问不能被优化掉或与其他序列化在 volatile 访问之前或之后的可见副作用重新排序。这使得 volatile 对象适合与信号处理程序通信,但不适合与另一个执行线程通信,参见 std::memory_order)。任何试图通过非 volatile 左值引用(例如通过指向非 volatile 类型的引用或指针)引用 volatile 对象的尝试都会导致未定义行为。

const volatile 对象 - 类型为 const-volatile 限定、const volatile 对象的非可变子对象、volatile 对象的 const 子对象或 const 对象的非可变 volatile 子对象。行为既像 const 对象又像 volatile 对象。

参考:Cpp reference


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接