evgeniy8705
@evgeniy8705
Повелитель вселенной

Как использовать std::begin и std::end в функциях для массивов?

Подскажите как правильно написать функцию которая принимает массивы с элементами к примеру int чтобы внутри можно было использовать функции std::begin и std::end?
Нормально работает в итоге только шаблонная функция, а вот как написать функцию конкретно для любой размерности массивов int не понятно.
И откуда шаблонная функция узнает размер массива если он не указывается явно и что тип будет именно массив в итоге? Та же функция baz для int не работает без указания явных размеров массивов.

#include <iostream>
#include <iterator>

template <typename T> void foo(const T& arra, const T& arrb);
void bar(const int (&arra)[], const int (&arrb)[]);
void baz(const int (&arra)[5], const int (&arrb)[5]);

int main()
{
	int arra[] = {1, 2, 3, 4, 5};
	int arrb[] = {1, 2, 3, 4, 5};

	foo(arra, arrb); // 1
	bar(arra, arrb); // Error
	baz(arra, arrb); // 1

	return 0;
}

template <typename T>
void foo(const T& arra, const T& arrb)
{
	auto arra_begin = std::begin(arra);

	std::cout << *arra_begin << std::endl; // 1
	std::cout << typeid(arra).name() << std::endl; // int const [5]
}

void bar(const int(&arra)[], const int(&arrb)[])
{
	auto arra_begin = std::begin(arra); // Error

	std::cout << *arra_begin << std::endl;
}

void baz(const int(&arra)[5], const int(&arrb)[5])
{
	auto arra_begin = std::begin(arra);

	std::cout << *arra_begin << std::endl; // 1
}
  • Вопрос задан
  • 210 просмотров
Пригласить эксперта
Ответы на вопрос 1
@Mercury13
Программист на «си с крестами» и не только
Я вообще не в курсе, как взаимодействуют Сишный int[] и Си++-ный &arr.
Но получается, это под капотом превращается в банальный const int*, для которого нет std::begin/end.

Я бы предложил ещё два распространённых механизма. Первый желательно делать лёгким инлайном, который под капотом превращается в data/size или std::span (если Си++20).

template <size_t N>
void myA(const int(&arra)[N], const int(&arrb)[N])
{
  auto arra_begin = std::begin(arra);

  std::cout << *arra_begin << std::endl; // 1
}

// Си++20!!!!!!!!!!
void myB(std::span<int> arra, std::span<int> arrb)
{
  auto arra_begin = std::begin(arra);

  std::cout << *arra_begin << std::endl; // 1
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы