string and size()

Greetings. The book I am reading ( c++ Primer ) says that the size() function of the string type returns a value of type string::size_type. If that is true, why does the following code work. It looks like size() is returning an int.

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>

using namespace std;

int main()
{
    string s1{"apples"};
    int sz = s1.size();

    cout << sz << "\n";

    return 0;
}
Last edited on
std::string is a type alias for std::basic_string< char, std::char_traits<char>, std::allocator<char> > std::string::size_type is a type alias for std::allocator_traits< std::allocator<char> >::size_type
which is a type alias for std::allocator<char>::size_type which is a type alias for std::size_t
The type size_t is an implementation-defined unsigned integer type that is large enough to contain the size in bytes of any object. - IS


When we write std::string s1{"apples"}; int sz = s1.size();
there is an implicit conversion from the "implementation-defined unsigned integer type" to int.
On almost all implementations, this would be a narrowing conversion

1
2
3
4
5
6
7
std::string s1{"apples"}; 

std::size_t sz = s1.size(); // good
std::string::size_type sz1 = s1.size(); // pedantically good
auto sz2 = s1.size(); // best. let the compiler figure out what the type is.

int sz3 = { s1.size() } ; // typically: *** error: narrowing conversion  
closed account (E0p9LyTq)
The return type from std::string::size is a size_t. http://www.cplusplus.com/reference/string/string/size/

size_t is an unsigned integral type (the same as member type string::size_type).


size_t is an
Alias of one of the fundamental unsigned integer types.
http://www.cplusplus.com/reference/cstddef/size_t/?kw=size_t
The return type from std::string::size is a size_t.

and not a size_type? Then I guess either the book has it wrong or I can't read.

Anyways guys, thanks for the input. I intend to review all of this in the coming days. At which time you'll probably hear from me again on this topic.
> The return type from std::string::size is a size_t.
>> and not a size_type?

std::string::size_type and std::size_t are the same type.

However, std::basic_string< char, std::char_traits<char>, my_custom_allocator<char> >::size_type
need not necessarily be std::size_t
Lippman in his book C++ Primer uses the type quite a bit in examples where it seems a simple int will do. for example the following code which is intended to count punctuation characters in a string is typical. Note the use of decltype( s.size() ).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>

using namespace std;

int main()
{
    string s( "Hello World!!!" );
    decltype( s.size() ) punct_cnt = 0;
    for( auto c : s )
        if( ispunct(c))
            ++punct_cnt;

    cout << punct_cnt << " punctuation characters in " << s << endl;

    return 0;
}
> Lippman in his book C++ Primer uses the type quite a bit in examples where it seems a simple int will do

In this particular example, we know that the size of the string is limited and a simple int or short would do.

Using the size_type of the sequence is a good habit to get into; if we do that instinctively, every time, the code that we write would be robust under all situations.
(The size of the sequence may not always be known at the time we write the code.)
It's also worth pointing out that using the appropriate size_types instead of ints as index variables in my for-loops eliminated all the compiler warnings about comparison between signed and unsigned integer expressions in my loop conditions

Thanks for the insights.
Topic archived. No new replies allowed.