Use the non-member std::begin()/std::end() function and the other variants, as well as std::data(), std::size() and std::empty() with:
- Standard containers:
std::vector<int> v1{ 1, 2, 3, 4, 5 };
auto sv1 = std::size(v1); // sv1 = 5
auto ev1 = std::empty(v1); // ev1 = false
auto dv1 = std::data(v1); // dv1 = v1.data()
for (auto i = std::begin(v1); i != std::end(v1); ++i)
std::cout << *i << std::endl;
std::vector<int> v2;
std::copy(std::cbegin(v1), std::cend(v1),
std::back_inserter(v2));
- (C-like) arrays:
int a[5] = { 1, 2, 3, 4, 5 };
auto pos = std::find_if(std::crbegin(a), std::crend(a),
[](int const n) {return n % 2 == 0; });
auto sa = std::size(a); // sa = 5
auto ea = std::empty(a); // ea = false
auto da = std::data(a); // da = a
- Custom types that provide corresponding member functions, begin()/end(), data(), empty(), or size():
dummy_array<std::string, 5> sa;
dummy_array<int, 5> sb;
sa[0] = "1"s;
sa[1] = "2"s;
sa[2] = "3"s;
sa[3] = "4"s;
sa[4] = "5"s;
std::transform(
std::begin(sa), std::end(sa),
std::begin(sb),
[](std::string const & s) {return std::stoi(s); });
// sb = [1, 2, 3, 4, 5]
auto sa_size = std::size(sa); // sa_size = 5
- Generic code where the type of the container is not known:
template <typename F, typename C>
void process(F&& f, C const & c)
{
std::for_each(std::begin(c), std::end(c),
std::forward<F>(f));
}
auto l = [](auto const e) {std::cout << e << std::endl; };
process(l, v1); // std::vector<int>
process(l, a); // int[5]
process(l, sa); // dummy_array<std::string, 5>