Void const là gì?


89

Mô tả của std::is_voidtiểu bang rằng:

Cung cấp giá trị hằng số thành viên bằng true, nếu T là kiểu void, const void, portable void, hoặc const variable void.

Sau đó, những gì có thể được const void, hoặc một volatile void?

Câu trả lời này nói rằng const voidkiểu trả về sẽ không hợp lệ (tuy nhiên được biên dịch trên VC ++ 2015)

const void foo() { }

Nếu theo tiêu chuẩn, const voidlà không hợp lệ (VC bị sai) - thì là const voidgì?


15
Câu trả lời bạn liên kết đến không nói rằng nó sẽ không hợp lệ, nó nói rằng nó sẽ là "vô nghĩa", mà tôi muốn hiểu là "không cung cấp bất kỳ lợi ích nào voidnếu không có const".

@hvd, câu trả lời nói rằng trình biên dịch nên cảnh báo / lỗi về trình độ đó. Bởi rằng tôi đoán chuẩn C ++ không cho phép trình độ vớivoid
Ajay

2
Câu trả lời nói rằng trình biên dịch nên cảnh báo về trình độ như vậy, nó không đề cập đến lỗi và một lỗi sẽ là sai. Nhận xét đó chỉ là về chất lượng thực hiện, không phải về sự phù hợp, nhưng tôi có thể hiểu rằng điều đó không rõ ràng chút nào từ bản thân nhận xét.

@Ajay tiêu chuẩn không chỉ định rằng phải có cảnh báo khi bạn sử dụng mã vô nghĩa. Đó là một quyết định của gcc để cung cấp cho bạn một gợi ý bổ sung rằng mã này không có tác dụng gì. Nhưng VC không sai theo bất kỳ cách nào.
user1942027

3
@Ajay Câu trả lời nói rằng clang đưa ra một cảnh báo và theo ý kiến ​​của tác giả, các trình biên dịch khác nên làm như vậy. Nếu tiêu chuẩn không cho phép, nó sẽ là một lỗi, không phải là một cảnh báo.
molbdnilo

Câu trả lời:


94

const voidlà một kiểu mà bạn có thể tạo một con trỏ tới. Nó tương tự như một con trỏ void thông thường, nhưng các chuyển đổi hoạt động khác. Ví dụ, a const int*không thể được chuyển đổi hoàn toàn thành a void*, nhưng nó có thể được chuyển đổi hoàn toàn thành a const void*. Tương tự như vậy, nếu bạn có một const void*bạn không thể static_castnó đến một int*, nhưng bạn có thể static_castnó vào một 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
Mặc dù câu trả lời của bạn là tốt, nhưng nó không nêu lý do của nó const void, nhưng nó xoay quanh các con trỏ void và non-void [with (non-) const-ness].
Ajay

26
@Ajay: Tôi không đồng ý. A const void*là lý do duy nhất bạn từng thấy const void. Nó có thể được chuyển xung quanh như một đối số mẫu, nhưng loại đối số đó sẽ chỉ được khởi tạo bằng một ký tự *ở cuối nó.
Benjamin Lindley

@BenjaminLindley Bạn cũng có thể thấy const voidtrong câu hỏi của luật sư ngôn ngữ
cpplearner

3
@Ajay: Tại một số điểm, câu hỏi này trở thành một câu hỏi triết học. "Lý do" const voidlà tất cả các kiểu trong C ++ đều có thể được thực hiện const. Nó "tồn tại" trong cùng một cách voidtồn tại. Câu trả lời của @Benjamin Lindley giải thích nó là gì thông qua thời điểm bạn nhìn thấy nó và cách bạn sử dụng nó.
Chris Beck

23

As void, const voidlà một kiểu trống. Tuy nhiên, nếu const voidlà kiểu trả về thì kiểu constnày là vô nghĩa (mặc dù hợp pháp!), Bởi vì [expr] / 6 :

Nếu một giá trị prvalue ban đầu có kiểu “ cv T ”, trong đó Tlà kiểu không phải lớp, không phải mảng, không đủ tiêu chuẩn cv, thì kiểu của biểu thức được điều chỉnh thành Ttrước khi phân tích thêm.

Tuy nhiên, bản thân nó là một kiểu hợp lệ và xuất hiện trong các hàm thư viện chuẩn C, ví dụ , nó được sử dụng để đảm bảo tính đúng hằng của con trỏ đối số: int const*không thể chuyển đổi thành void*, nhưng void const*.


const voidnhư kiểu trả về ảnh hưởng đến kiểu hàm, vì vậy nó không hoàn toàn vô nghĩa.
cpplearner

1
@cpplearner Ngoại trừ nó theo mọi nghĩa thực tế, vì cả chữ ký của hàm cũng như loại lệnh gọi đến nó đều không bị ảnh hưởng.
Columbo

Nó có thể thay đổi chữ ký của một mẫu hàm. 1 dù sao
cpplearner

@cpplearner Đủ công bằng - mặc dù vậy, nó vẫn rất lãng phí các lần nhấn phím.
Columbo

Chúng ta thường thấy: const int * không thể chuyển đến void *, nhưng const void *.
mgouin

18

Các loại có thể là kết quả của các mẫu; một mẫu có thể nêu const T, và được khởi tạo với Tnhư void.

Câu trả lời được liên kết bị đánh lừa, hay nói đúng hơn là bị hạn chế về quan điểm ở chỗ nó liên quan đến trường hợp đặc biệt của loại không phải mẫu và thậm chí sau đó const voidcó thể vô nghĩa , nhưng nó là mã hợp lệ .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.