When you need to use decltype in C ++

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

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 that the code is the first word in the line, and the output

 SOME string 

I'm curious why you need to use decltype(s.size()) to declare a type for an index. If I change it to int index =0 , the code will still compile and run without problems. It seems easier to use int . I think that some kind of import concept is missing here, any feedback will be really useful. Thanks!

+7
c ++
source share
5 answers

You do not need to use decltype(s.size()) to declare a type, but declaring it as an int not necessarily a good idea. Or at least it's not a good habit to join.

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

Please note that in my code I just simply write for(size_t index = 0; index < string.size(); index++) , because it is 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.

+6
source share

The resonance that they used decltype(s.size()) instead of int is because using int can cause an overflow, which is undefined. std::string::size() returns an unsigned integer type that can hold the largest size string you can make. If int cannot hold this value, and the string is size, then trying to execute int on this value will never work

Prior to C ++ 11, you would have to use std::string::size_type , and if you changed the type, you would have to change the std::string . Now that we have C ++ 11 and above, we no longer need to do this. The compiler knows what the type of things is, if we use decltype(s.size()) , we get the correct type, and if we ever change what s , there is nothing in the for loop that needs to be changed. This is really good in terms of maintainability.

+2
source share

When you need to use decltype in C ++

I can think of the following.

If you want the compiler to infer a type from:

  • Another type of object.
  • The return type of the function.

You could also use:

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

The reason is that the type of the s.size() function is a member of the string string::size_type that is unsigned and can hold any string length. In this code, index has a variable that increases as the loop starts and increases until its value becomes s.size()-1 . The string length can be any size. Therefore, we cannot use int for longer strings, because it can only contain the value of a certain range. Therefore, if the length of the string is greater than the size of index , it can hold a value of any size without any error.

+1
source share

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 propagate two things together, possibly of different types, and return something like the correct type of the result of multiplying these two. A hypothetical example is the multiplication of two matrices together, which leads to some class of intermediate type that postpones the actual calculation to a much later time.

+1
source share

All Articles