The declaration of C++ string is the following:
template<
class CharT,
class Traits = std::char_traits<CharT>,
class Allocator = std::allocator<CharT>
> class basic_string;
The CharT
is character type which can be char
, wchar_t
, char16_t
and char32_t
; but after all basic_string
is a template so can be instantiated with other CharT
and other allocators. While I can think in some use cases for other allocators I'm unable to think in use cases for strings of other data types, for example:
using string = std::basic_string<int>;
Using a string of integers, we cannot initialize it as a string (obvious) nor u32 string (not that obvious, at least for me); but we can initialize it with initializer_list
as long as the contained type of the list is convertible to int
:
string err1("test"); // Error!
string err2(U"test"); // Error!
string err3{"test"}; // Error!
string err4{U"test"}; // Error!
string err5 = "test"; // Error!
string err6 = U"test"; // Error!
string success1({U't', U'e', U's', U't'});
string success2 = {U't', U'e', U's', U't'};
string success3({'t', 'e', 's', 't'});
string success4 = {'t', 'e', 's', 't'};
But even if we manage to initialize a integer string, we cannot use it in the normal way:
std::cout << success1; // Error! expected 116101115116
The only basic_string
expected to be used with cout
are the normal ones, that makes sense: after all we cannot assume how is supposed to be printed a string of integers or a string of MyFancyClass
es.
But anyways, the creation of strange instances of basic_string
isn't forbidden; on one hand is not forbidden due to the lack of features which forbids that use (a.k.a. concepts) and on the other coding basic_string
without limiting the underlying type is easier than doing it on the opposite way (without concepts) so, that makes me wonder:
std::basic_string<T>
where T
is not a character type?As for any use I'm thinking about things that only can be achieved with strings of T
and that cannot be done with vector of T
(or it will be significantly harder to do), in other words:
T
is the better choice?The sequences controlled by an object of type basic_string are the Standard C++ string class and are referred to as strings, but they shouldn't be confused with the null-terminated C-style strings used throughout the C++ Standard Library.
The std::string type is the main string datatype in standard C++ since 1998, but it was not always part of C++. From C, C++ inherited the convention of using null-terminated strings that are handled by a pointer to their first element, and a library of functions that manipulate such strings.
In C++, you should use the string header. Write #include <string> at the top of your file. When you declare a variable, the type is string , and it's in the std namespace, so its full name is std::string .
If you are dealing with a system that handles multiple text encodings (e.g. ASCII and EBCDIC), you might want a separate character type and string type for each encoding. They should both be treated as strings, but are clearly distinct types.
When building a tokenizer, char[n] or enum comes into mind. Note that constructor of Token is not run by basic_string.
#include <iostream>
#include <string>
#include <string.h>
static const int max_token_length = 10;
struct Token
{
char str[max_token_length];
};
// define std::char_traits<Token> if your implementation defaults are not fine for you (or don't exist as it's not required)
int main() {
Token t;
strncpy( t.str, "for", max_token_length );
std::basic_string<Token> s1( 1, t );
Token u;
strncpy( t.str, "for", max_token_length );
std::basic_string<Token> s2( 1, u );
std::basic_string<Token> s = s1 + s2;
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With