#c
#c
Вопрос:
допустим, у меня есть функция
auto found = find(first, last, condition);
Эта находка должна быть способна обещать не изменять от первого до последнего.
Итак, что-то вроде
auto find(const T* first, const T* last, Comp c = less<>);
в результате возвращается значение const T или const T* .
итак
int arr[] = {3, 4};
std::vector v(arr, arr 2);
int* found = find(v.begin(), v.end());
** error found is non-const.
Я хочу изменить *найдено! Какие у меня варианты? перегрузки?
Комментарии:
1.
const* T first
похоже, вы имеете в виду недопустимый синтаксисT const* first
. Но еслиT
это параметр шаблона, как это звучит, тоconst
(или его отсутствие) может быть скрыто внутриT
…2. Вы хотите запретить обычный итератор и потребовать const_iterator ?
3. Спасибо, Бен, я хотел бы обеспечить постоянство даже с шаблонами.
4. @Jarod42 Я хочу улучшить постоянство.
5. Есть ли у вас доступ к C 20 (с концепцией или
std::span<const T>
), иначе SFINAE может быть подходящим вариантом.
Ответ №1:
У вас не может быть такой подписи
int* my_find(const int* begin, const int* end);
(для сигнализации о том, что ваш метод не изменяет диапазон)
без (опасно) /*const_*/cast
.
Эта подпись позволила бы
const int arr[] = {0, 1, 2, 3};
*my_find(std::cbegin(arr), std::cend(arr)) = 42; // Modifying const object. -> UB
Возможность состояла бы в том, чтобы на месте вызова провести весь кастинг:
// const int* my_find(const int*, const int*);
int arr[] = {0, 1, 2, 3};
auto it = const_cast<int*>(my_find(std::cbegin(arr), std::cend(arr)));
Это предполагает, что возвращаемый указатель находится в диапазоне, а не указатель на внешний объект const (сигнатуры не могут этого гарантировать (Rust имеет дополнительное время жизни в type, что подтверждает немного больше этого предположения 🙂 )).
Комментарии:
1. Было бы неплохо иметь возможность обернуть это приведение в перегрузку. увы, мы здесь. Спасибо за ваш вклад.