Подтвердить что ты не робот

Какой смысл 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 имеет какое-либо практическое значение?

4b9b3361

Ответ 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*.