# std::ranges::data

< cpp‎ | ranges
 Defined in header  inline namespace /*unspecified*/ {     inline constexpr /*unspecified*/ data = /*unspecified*/; } (since C++20) (customization point object) Call signature template< class T >     requires /* see below */ constexpr std::remove_reference_t>* data(T&& t);

Returns a pointer to the first element of a contiguous range.

If the argument is an lvalue or is true, a call to ranges::data is expression-equivalent to:

1. std::forward<T>(t).data(), if that expression is valid, and its return type is a pointer to an object type.
2. Otherwise, std::to_address(ranges::begin(std::forward<T>(t))), if ranges::begin(std::forward<T>(t)) is valid and returns a type that models std::contiguous_iterator.
If is incomplete, then ranges::data(std::forward<T>(t)) is ill-formed, no diagnostic required.

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.

## Contents

### Expression-equivalent

Expression e is expression-equivalent to expression f, if e and f have the same effects, either are both potentially-throwing or are both not potentially-throwing (i.e. noexcept(e) == noexcept(f)), and either are both constant subexpressions or are both not constant subexpressions.

###  Customization point objects

The name ranges::data denotes a customization point object, which is a const function object of a literal semiregular class type. For exposition purposes, the cv-unqualified version of its type is denoted as __data_fn.

All instances of __data_fn are equal. The effects of invoking different instances of type __data_fn on the same arguments are equivalent, regardless of whether the expression denoting the instance is an lvalue or rvalue, and is const-qualified or not (however, a volatile-qualified instance is not required to be invocable). Thus, ranges::data can be copied freely and its copies can be used interchangeably.

Given a set of types Args..., if std::declval<Args>()... meet the requirements for arguments to ranges::data above, __data_fn models std::invocable<__data_fn, Args...>, std::invocable<const __data_fn, Args...>, std::invocable<__data_fn&, Args...>, and std::invocable<const __data_fn&, Args...>. Otherwise, no function call operator of __data_fn participates in overload resolution.

### Notes

If the argument is an rvalue (i.e. T is an object type) and 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.

### Example

#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!