std::ranges::data(3)
π std::ranges::data π
hey bestie π«Ά welcome to the std::ranges::data page from the C++ Standard Libary manual. this one is a customization point object and it's giving βpointer to the first element of a contiguous rangeβ main character energy. let's get into it β¨
π NAME π
std::ranges::data - std::ranges::data
okay yes the name is literally the same twice, no cap π that's how the page says it.
β¨ Synopsis β¨
okay so first: it's defined in header <ranges>. it's also defined in header <iterator>.
then the synopsis goes like this:
inline namespace /* unspecified */ {
inline constexpr /* unspecified */ data = /* (since C++20)
unspecified */;
(customization point object)
}
(that (customization point object) note? yes bestie, that's what it is π
)
π Call signature π
the call signature is:
template< class T >
requires /* see below */ (since C++20)
constexpr std::remove_reference_t<
ranges::range_reference_t<T>>* data( T&& t );
and what does it do? it returns a pointer to the first element of a contiguous range. periodt π₯
now the caveats, because of course there are caveats:
if T is an array type and std::remove_all_extents_t<std::remove_reference_t<T>> is incomplete, then the call to ranges::data is ill-formed, no diagnostic required. (translation: the compiler can just refuse without a cute little error message π)
if the argument is an lvalue or ranges::enable_borrowed_range<std::remove_cv_t<T>> is true, a call to ranges::data is expression-equivalent to:
decay-copy(t.data())(until C++23) orauto(t.data())(since C++23), if that expression is valid and its type is a pointer to an object type.- otherwise,
std::to_address(ranges::begin(t)), if the expressionranges::begin(t)is valid and its type modelsstd::contiguous_iterator.
in all other cases, a call to ranges::data is ill-formed, which can result in substitution failure when ranges::data(e) appears in the immediate context of a template instantiation. so yeah, vibe check can fail at compile time π
π§ Notes π§
if the argument is an rvalue (i.e. T is an object type) and ranges::enable_borrowed_range<std::remove_cv_t<T>> is false, the call to ranges::data is ill-formed, which also results in substitution failure.
if ranges::data(e) is valid for an expression e, then it returns a pointer to an object.
the C++20 standard requires that if the underlying data function call returns a prvalue, the return value is move-constructed from the materialized temporary object. all implementations directly return the prvalue instead. the requirement is corrected by the post-C++20 proposal P0849R8 to match the implementations. (so the standard had a little oopsie and P0849R8 fixed the fit π
)
π Example π
// Run this code
#include <cstring>
#include <iostream>
#include <ranges>
#include <string>
int main()
{
std::string s{"Hello world!\n"};
char a[20]; // storage for a C-style string
std::strcpy(a, std::ranges::data(s));
// [data(s), data(s) + size(s)] is guaranteed to be an NTBS
std::cout << a;
}
π» Output π»
Hello world!
π See also π
ranges::cdataβ obtains a pointer to the beginning of a read-only contiguous range (C++20) (customization point object)ranges::beginβ returns an iterator to the beginning of a range (C++20) (customization point object)dataβ obtains the pointer to the underlying array (C++17) (function template)
okay that's the whole page, bestie π«Ά sourced from http://cppreference.com, version/date 2024.06.10, and it's the std::ranges::data(3) page. byeee πβ¨
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms