简体   繁体   中英

Double/Integer use and data narrowing within a Range-Based for loop

I am working my way through Bjarne Stroustrup's Programming Principles and Practice and am having difficulty. I am currently reading on Vectors and have been introduced to Range-based for loops. Below I have some code, that from my eyes, appears to be reading a double into an INT; which I assume causes narrowing.

int main()
{
    vector<double> temps;               // temperatures
    for (double temp; cin >> temp; )    // read into temp
        temps.push_back(temp);          // put temp into vector
                                        // compute mean temperature:
    double sum = 0;
    for (int x : temps) sum += x;
        cout << "Average temperature: " << sum / temps.size() << '\n'; 
                                        // compute median temperature:
    sort(temps);                        // sort temperatures
    cout << "Median temperature: " << temps[temps.size() / 2] << '\n';
    keep_window_open();
    return 0;
}

Upon trying this a few times with different inputs I have arrived at the conclusion this is indeed narrowing. I am creating a vector of doubles and than in the for(int x : temps) loop, taking the first element within temp, putting it within x, processing it than incrementing to the next element and repeating. Because the element (a double) is being read into x (an integer) causing the narrowing.

My main question is if I am indeed correct it is narrowing the elements within the vector (maybe it doesn't actually read into x and that int x is describing something else), can I simply replace for(int x : temps) to for(double x : temps) to avoid this narrowing, or is the use of an integer in the range-based for loop parameters mandatory (maybe designed that way). Any thoughts, thanks.

It is a narrowing conversion, yes (Section 11.6.4 aka [dcl.init.list] of the C++ standard , item 7.1). I would guess it's a mis-type. Pretend it said double x (or auto x if you already know about the auto keyword, which makes the compiler deduce the type if possible).

I can't find this in the 2nd edition errata though. I'd actually drop Prof. Stroustrup a line and ask him (don't be shy - as you can see, the book has a bunch of errors, he should be appreciative of the question).

  1. Yes, you can use any type to initialize your for loop variable (any version of it).
  2. Yes, any conversion from floating point type to integer type in C/C++, always return the truncated value of this number ( floor operation).

Please, take a look at C++ casting rules:

If the conversion is from a floating-point type to an integer type, the value is truncated (the decimal part is removed). If the result lies outside the range of representable values by the type, the conversion causes undefined behavior.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM