Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When do you require to use decltype in C++

Tags:

c++

I am learning C++ and have found the following code in C++ primer:

int main() {

string s("some string");
for(decltype(s.size()) index = 0; index != s.size() && !isspace(s[index]); ++index)
    s[index] = toupper(s[index]);

cout << s;

}

I understand the code capitalized the first word in the string and the output is

SOME string

What I am curious is that why do you need to use decltype(s.size()) to declare the type for index. If I change it to int index =0, the code still compile and run with no problem. It seems easier for me to use int. I think I am missing some import concept here, any feedback will be really helpful. Thanks!

like image 636
SunnyIsaLearner Avatar asked Mar 24 '17 18:03

SunnyIsaLearner


2 Answers

You're not required to use decltype(s.size()) to declare the type, but declaring it as int isn't necessarily a good idea. Or at least it's not a good habit to get into.

decltype(s.size()) literally means "this type should be the same as whatever std::string uses to store the length of the string". In most C++ implementations, this is size_t, which will either be an unsigned 64-bit integer (in most cases) or an unsigned 32-bit integer. In either situation, int (which is signed and is probably not going to be 64-bits) is not going to represent the entire possible range of sizes for std::string objects, which could, in exotic situations, be greater than 2.1 billion characters. In those situations, if you defined the type as int, you'd run the risk of undefined behavior.

Note that in my code, I often just write for(size_t index = 0; index < string.size(); index++), because that's simpler. But if you want to guarantee that the code will behave on all platforms, for(decltype(string.size()) index = 0; index < string.size(); index++) is the safest version of the code.

like image 153
Xirema Avatar answered Sep 18 '22 16:09

Xirema


The reson they used decltype(s.size()) instead of int is because using int could cause a overflow which is undefined behavior. std::string::size() returns a unsigned integer type that can store the largest size string you can make. If int cannot hold that value and the string is that size then trying to run a int to that value will never work

Before C++11 you would have had to use std::string::size_type and if you changed the type then you would have to change the std::string part. Now that we have C++11 and above we no longer need to do that. The compiler knows what the type of things are so if we use decltype(s.size()) we get the right type and if we ever change what s is there is nothing in the for loop that needs to be changed. This is really nice from a maintainability stand point.

like image 35
NathanOliver Avatar answered Sep 19 '22 16:09

NathanOliver