SunnyIsaLearner
SunnyIsaLearner

Reputation: 780

When do you require to use decltype in 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!

Upvotes: 9

Views: 1709

Answers (5)

Andre Kostur
Andre Kostur

Reputation: 780

Well, one place where decltype would be more useful would be:

template<class T1, class T2>
auto mul(T1 a, T2 b) -> decltype(a*b){
  return a*b;
}

This template will allow you to multiply two things together, possibly of different types, and will return something of the correct type of the result of multiplying the two together. A hypothetical example might be multiplying two matricies together that results in some intermediate type class that defers the actual calculation until much later.

Upvotes: 2

Utkarsh Verma
Utkarsh Verma

Reputation: 11

The reason is that the type of s.size() member function of string class is string::size_type which is unsigned and can hold any length of string. In this code index is a variable that increase as the loop runs and it will increase until its value becomes equal to s.size()-1. The length of string can be of any size.So we can't use int for longer strings because it can hold value of only specific range.So if string is longer in size index can hold the value of any size without showing any error.

Upvotes: 1

Xirema
Xirema

Reputation: 20386

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.

Upvotes: 8

R Sahu
R Sahu

Reputation: 206557

When do you require to use decltype in C++

I can think of the following.

When you want the compiler to deduce a type from:

  1. Another object's type.
  2. A function's return type.

You could have also used:

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

Upvotes: 1

NathanOliver
NathanOliver

Reputation: 180415

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.

Upvotes: 3

Related Questions