Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any use for basic_string<T> where T is not a character type?

Tags:

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 MyFancyClasses.

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:

  • Is there any use for 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:

  • Have you ever faced a situation where a string of T is the better choice?
like image 658
PaperBirdMaster Avatar asked Mar 03 '16 14:03

PaperBirdMaster


People also ask

What is basic_ string in C++?

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.

What is std::string?

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.

How do you insert std::string?

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 .


2 Answers

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.

like image 140
joelw Avatar answered Sep 30 '22 23:09

joelw


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;
}
like image 44
lorro Avatar answered Oct 01 '22 00:10

lorro