const void是什么意思,它是一个有效的返回类型吗?

96

std::is_void的描述如下:

如果T是void类型、const void类型、volatile void类型或const volatile void类型,则提供等于true的成员常量值。

那么const voidvolatile void可能是什么?

这个答案指出const void返回类型将是无效的(然而在VC++ 2015上可以编译)。

const void foo() { }

如果按照标准来说,const void是无效的(VC是错误的)-那么const void是什么意思?

15
您提供的答案没有说它是无效的,而是说它是“没有意义的”,这意味着“与没有 constvoid 相比没有任何优势”。 - user743382
@hvd,答案中提到编译器应该对这种限定发出警告/错误。由此我推测C++标准不允许使用void进行限定。 - Ajay
2
答案指出编译器应该警告这种限定符,但没有提到错误,而错误是不正确的。那个备注只是关于实现质量,而不是符合性,但我可以理解从备注本身来看这一点并不清楚。 - user743382
@Ajay,标准并没有规定在使用无意义代码时应该发出警告。这是gcc的决定,为了给你一个额外的提示,表明这段代码什么也没做。但VC并没有任何错误。 - AliciaBytes
3
这段话的意思是:回答中提到了clang会发出警告,而根据作者的观点,其他编译器也应该发出警告。如果标准不允许这样做,那么这将是一个错误而不是警告。 - molbdnilo
3个回答

98

const void 是一种可以形成指针的类型。它类似于普通的 void 指针,但转换方式不同。例如,const int* 不能隐式转换为 void*,但可以隐式转换为 const void*。同样地,如果你有一个 const void*,你不能将其 static_cast 为一个 int*,但可以将其 static_cast 为一个 const int*

const int i = 10;
void* vp = &i;                           // error
const void* cvp = &i;                    // ok
auto ip = static_cast<int*>(cvp);        // error
auto cip = static_cast<const int*>(cvp); // ok

4
虽然你的答案很好,但它没有说明“const void”的原因,而是围绕着void和非void指针[与(非)const-ness]。 - Ajay
27
我不同意。在const void*中,const void是唯一出现的情况。虽然它可能会作为模板参数传递,但该参数类型只会使用末尾带有*的实例化。 - Benjamin Lindley
@BenjaminLindley 你可能也会在由语言律师提出的问题中看到 const void - cpplearner
3
某个时刻,这个问题变成了哲学问题。const void 的“原因”是因为在C++中所有类型都可以被声明为 const。它的“存在”方式与 void 相同。@Benjamin Lindley的回答通过使用方法和如何使用来解释了它的含义。 - Chris Beck

23
作为 voidconst void 是一种空类型。但是,如果 const void 是一个 返回 类型,则 const 是无意义的(尽管合法!),因为根据[expr]/6

如果 prvalue 最初具有类型“cv T”,其中 T 是 cv-未限定的非类、非数组类型,则在进一步分析之前将表达式的类型调整为 T

然而,它本身是一个有效的类型,并出现在例如C标准库函数中,这些函数用于确保参数指针的 const-correctness:int const* 不能转换为 void*,但可以转换为 void const*


const void 作为返回类型确实会影响函数类型,因此它并不是完全没有意义的。 - cpplearner
1
@cpplearner,实际上它几乎是一样的,因为函数的签名和对它的调用类型都不会受到影响。 - Columbo
它可以改变函数模板的签名。尽管如此,还是要加1。 - cpplearner
@cpplearner 很好 - 但仍然浪费了键盘击键。 - Columbo
通常我们会看到:const int * 不能转换为 void *,但 const void * 可以。 - mgouin

18

类型可以是模板的结果;一个模板可能声明const T,并且使用T作为void实例化。

链接的答案误导了人们,或者说视野有限,因为它只涉及非模板类型的特殊情况,即使在这种情况下,const void也可能是无意义的,但它是有效的代码


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