Какой смысл const void?
По-видимому, можно объявить функцию, возвращающую const void
:
const void foo()
{
}
g++, по-видимому, считает важность const
важной, поскольку следующий код не компилируется:
#include <type_traits>
static_assert(std::is_same<void(), const void()>::value, "const matters");
Значит, const void
имеет какое-либо практическое значение?
Ответы
Ответ 1
Не совсем. Но игнорировать cv-квалификацию на void или делать их ошибки могут создать ненужную сложность с точки зрения как реализации компилятора, так и кода конечного пользователя. Рассмотрим шаблоны типа
template<typename T>
const T ...
Нет причин для того, чтобы использовать void в этом сценарии особый случай (больше, чем он уже есть), он просто создавал бы головные боли.
Кроме того, в то время как const void
не помогает, const void*
использует его.
Ответ 2
const void
разрешается просто потому, что нет смысла заставить компилятор выкинуть это одно исключение из общего правила и не навредить ему.
Существует некоторое обсуждение выше, что const void*
не очень полезно:
Насколько полезен const void *? Я вижу, как может быть void * const, но не первый. -Spidey
На самом деле const void*
иногда является существенным.
Он заявляет, что указываемая вещь читается только в отличие от void* const
, которая только объявляет, что указатель сам по себе является постоянным, но не тем, на что он указывает.
По моему опыту, указатель на константу, использующий const void*
, более полезен из двух форм. Конечно, существует также const void* const
, означающее, что и указатель, и то, на что он указывает, являются постоянными.
void*
обычно используется как способ передачи неспецифических указателей (например, с помощью memcpy()
).
Если вы хотите передать const char*
такой функции, вы не сможете использовать void*
или потеряете тот факт, что предмет, на который он указывает, является постоянным и не может быть изменен. Текущие компиляторы С++ откажутся от компиляции, так как это должно было бы неявно отбрасывать const
и, по праву, так как эти данные могут быть в памяти только для чтения и, возможно, вызывать исключение, если что-либо пытается записать на него.
Вот почему второй аргумент memcpy()
равен const void*
, а не просто void*
.