значение, возвращаемое из функции с постоянным диапазоном в качестве аргументов

#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. Было бы неплохо иметь возможность обернуть это приведение в перегрузку. увы, мы здесь. Спасибо за ваш вклад.