Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is std::string() the same as std::string("")

Tags:

c++

c++11

Suppose I have a function that returns a std::string. Certain circumstances mean that the string is not populated with anything.

Is returning std::string() exactly equivalent to std::string("")? For example, would c_str() or data() give you the same character sequence? Perhaps the std::string("") invokes a short string optimisation but std::string() does no such thing until some characters are added.

Does anyone know if the current standard (C++11) says anything definitive?

like image 983
P45 Imminent Avatar asked Nov 11 '14 13:11

P45 Imminent


4 Answers

There's certainly no member function on std::string that would allow you to distinguish between a std::string() and a std::string("").

I defer to a philosopher or logician to verify if that satisfies any definition of equality.

As for the standard itself, it states that std::string() will leave the capacity unspecified but std::string("") will define a capacity of at least zero. So the internal state of the object could be different.

On my particular STL implementation (MSVC2012), std::string() calls a function called _Tidy whereas std::string("") calls _Tidy and assign. (The base class initialisation is identical). assign is a standard std::string function.

So could they be different? Yes. Can you tell if they are different? No.

like image 104
Bathsheba Avatar answered Nov 14 '22 23:11

Bathsheba


If we look at the effects of each constructor in the C++ standard, section § 21.4.2 [string.cons] :

For explicit basic_string(const Allocator& a = Allocator()) :

  • data() : a non-null pointer that is copyable and can have 0 added to it
  • size() : 0
  • capacity() : an unspecified value

For basic_string(const charT* s, const Allocator& a = Allocator()) :

  • data() : points at the first element of an allocated copy of the array whose first element is pointed at by s
  • size() : traits::length(s)
  • capacity() : a value at least as large as size()

So strictly speaking, both constructs are not identical : in particular, the capacity of the constructed std::string objects might be different.

In practice, it's unlikely that this possible difference will have any observable effect on your code.

like image 43
quantdev Avatar answered Nov 15 '22 00:11

quantdev


Yes, they are both same. Default constructor of std::string prepares an empty string same as ""

explicit basic_string( const Allocator& alloc = Allocator() );
Default constructor. Constructs empty string (zero size and unspecified capacity)

basic_string( const CharT* s, const Allocator& alloc = Allocator() );
Constructs the string with the contents initialized with a copy of the null-terminated character string pointed to by s. The length of the string is determined by the first null character. The behavior is undefined if s does not point at an array of at least Traits::length(s)+1 elements of CharT.

like image 3
Mohit Jain Avatar answered Nov 14 '22 23:11

Mohit Jain


The only difference is that std::string() knows at compile-time that it will produce a zero-length string, while std::string("") has to use strlen or something similar to determine the length of the string it will construct at run-time. Therefore the default-constructor should be faster.

like image 2
Joe Gottman Avatar answered Nov 14 '22 23:11

Joe Gottman