In C++, the type of string literals is const char [N]
, where N
, as std::size_t
, is the number of characters plus one (the zero-byte terminator). They reside in static storage and are available from program initialization to termination.
Often, functions taking a constant string doesn't need the interface of std::basic_string
or would prefer to avoid dynamic allocation; they may just need, for instance, the string itself and its length. std::basic_string
, particularly, has to offer a way to be constructed from the language's native string literals. Such functions offer a variant that takes a C-style string:
void function_that_takes_a_constant_string ( const char * /*const*/ s );
// Array-to-pointer decay happens, and takes away the string's length
function_that_takes_a_constant_string( "Hello, World!" );
As explained in this answer, arrays decay to pointers, but their dimensions are taken away. In the case of string literals, this means that their length, which was known at compile-time, is lost and must be recalculated at runtime by iterating through the pointed memory until a zero-byte is found. This is not optimal.
However, string literals, and, in general, arrays, may be passed as references using template parameter deduction to keep their size:
template<std::size_t N>
void function_that_takes_a_constant_string ( const char (& s)[N] );
// Transparent, and the string's length is kept
function_that_takes_a_constant_string( "Hello, World!" );
The template function could serve as a proxy to another function, the real one, which would take a pointer to the string and its length, so that code exposure was avoided and the length was kept.
// Calling the wrapped function directly would be cumbersome.
// This wrapper is transparent and preserves the string's length.
template<std::size_t N> inline auto
function_that_takes_a_constant_string
( const char (& s)[N] )
{
// `s` decays to a pointer
// `N-1` is the length of the string
return function_that_takes_a_constant_string_private_impl( s , N-1 );
}
// Isn't everyone happy now?
function_that_takes_a_constant_string( "Hello, World!" );
Why isn't this used more broadly? In particular, why doesn't std::basic_string
have a constructor with the proposed signature?
Note: I don't know how the proposed parameter is named; if you know how, please, suggest an edition to the question's title.