Что такое const void?

89

В описании std::is_voidговорится, что:

Предоставляет значение константы члена, равное true, если T является типом void, const void, volatile void или const volatile void.

Тогда что могло быть const void, или volatile void?

В этом ответе указано, что const voidтип возвращаемого значения будет недопустимым (однако компилируется на VC ++ 2015).

const void foo() { }

Если по стандарту const voidнедействителен (ошибочен VC) - тогда что const void?

Аджай
источник
15
В ответе, на который вы ссылаетесь, не говорится, что он был бы недействительным, он заявляет, что он был бы «бессмысленным», что, как я понимаю, означает «не дает никаких преимуществ voidбез const».
@hvd, в ответе указано, что компилятор должен предупреждать / об ошибке о такой квалификации. Исходя из этого, я полагаю, что стандарт C ++ не допускает квалификацию сvoid
Аджай
2
В ответе указано, что компилятор должен предупреждать о такой квалификации, он не упоминает об ошибке, и ошибка будет неправильной. Это замечание касается только качества реализации, а не соответствия, но я могу понять, что это совсем не ясно из самого замечания.
@Ajay стандарт не указывает, что при использовании бессмысленного кода должно быть предупреждение. Компания gcc решила дополнительно намекнуть, что этот код ничего не делает. Но VC в любом случае не ошибается.
user1942027
3
@Ajay В ответе указано, что clang выдает предупреждение, и что, по мнению автора, другие компиляторы должны. Если бы стандарт не допускал этого, это было бы ошибкой, а не предупреждением.
molbdnilo

Ответы:

94

const voidэто тип, на который можно сформировать указатель. Он похож на обычный указатель void, но преобразования работают по-другому. Например, const int*нельзя неявно преобразовать в a 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, но все вокруг пустые и непустые указатели [с (не) константностью].
Ajay
26
@Ajay: Я не согласен. А const void*- единственная причина, по которой вы когда-либо видели const void. Он может быть передан как аргумент шаблона, но этот тип аргумента может быть создан только с символом *в конце.
Бенджамин Линдли,
@BenjaminLindley Вы также можете увидеть const voidна вопрос , задаваемый на языке адвоката
cpplearner
3
@Ajay: В какой-то момент этот вопрос становится вопросом философии. «Причина» в const voidтом, что все типы в C ++ могут быть сделаны const. Он «существует» так же, как и voidсуществует. Ответ @Benjamin Lindley объясняет, что это такое, когда вы его видите и как вы его используете.
Крис Бек
23

As void, const voidявляется пустым типом. Однако, если const voidэто возвращаемый тип, constбессмысленно (хотя и разрешено!), Потому что [expr] / 6 :

Если prvalue изначально имеет тип « cv T », где Tcv-неквалифицированный неклассовый тип , не являющийся массивом, тип выражения корректируется Tдо любого дальнейшего анализа.

Однако это сам по себе допустимый тип и встречается, например, в функциях библиотеки C-стандарта , где он используется для обеспечения константной корректности указателей аргументов: int const*не может быть преобразован в void*, но void const*.

Коломбо
источник
const voidпоскольку возвращаемый тип влияет на тип функции, поэтому это не совсем бессмысленно.
cpplearner
1
@cpplearner За исключением того, что это во всех практических смыслах, потому что ни подпись функции, ни тип ее вызова не затрагиваются.
Columbo
Ну, он может изменить подпись шаблона функции. +1 тем не менее
cpplearner
@cpplearner Достаточно честно - хотя это все еще бесполезная трата нажатий клавиш.
Коломбо
Обычно мы видим: const int * не может перейти в void *, но const void *.
mgouin
18

Типы могут быть результатом шаблонов; шаблон может const Tсостоять и быть создан с помощью Tas void.

Связанный ответ вводится в заблуждение или, скорее, ограничен ввиду того, что он касается особого случая нешаблонного типа, и даже в этом случае const voidможет быть бессмысленным , но это действительный код .

DevSolar
источник