Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does map not include out_of_range?

Consider the following code that doesn't compile:

#include <map>

//#include <stdexcept>  // uncommenting this works

int main() {

    std::map<int, int> test;
    try {
        test.at(10);
    } catch(std::out_of_range& e) {
    }

    return 0;
}

Why does std::map not include std::out_of_range, even if it uses it? (The .at() can throw a std::out_of_range).

When I also include <stdexcept> it compiles, and works fine.

like image 751
Creepsy Avatar asked Dec 08 '20 16:12

Creepsy


People also ask

What is std out of range?

std::out_of_range It is a standard exception that can be thrown by programs. Some components of the standard library, such as vector , deque , string and bitset also throw exceptions of this type to signal arguments out of range. It is defined as: C++98. C++11.

How to throw out of range error c++?

To throw an out-of-range exception in C++, you can create an exception object. For this, you can use the out_of_range() constructor. The out_of_range() constructor is defined in the standard C++ library. It takes a string object as its input argument and returns an out-of-range exception.

What does a map that is not in normal range mean?

Below are the definitions of what it means when the MAP is not in a normal range and what is done to correct the problem: A MAP that is above 105mmHg indicates the heart has to work much harder than it should and can cause stress on the heart.

Can map () convert from positive to negative range?

TIP: map () can convert from positive ranges to negative ranges. Everything is fine 0 maps to 0, and 1023 maps to 255... ...with an even distribution (really?????).

What does the map function do in C?

The map function is intended to change one range of values into another range of values and a common use is to read an analogue input (10 bits long, so values range from 0 to 1023) and change the output to a byte so the output would be from 0 to 255.

What does it mean if my map is low?

A MAP can be low even if the systolic (top number) blood pressure is 80 to 100 mmHg. This is why it is important to calculate the MAP on every patient that goes into the acute care setting. Causes of low MAP include: Any condition that causes the body to lose blood pressure can cause a low MAP, so this is not limited to the conditions above.


3 Answers

Whether a standard header does include another header is an implementation detail unless explicitly specified.

With templates its a little more involved, but just to point you in some direction, consider this toy example:

// header: my_map.h
struct my_map {
    int at(int);
};

Only in the source file the header for the exception has to be included:

// source: my_map.cpp
#include <stdexcept>
int my_map::at(int) {
    throw std::out_of_range("bla");
}

std::map surely looks different but it may hide the exception from the header as well.


Is it also ok for a header to not include a decl for std::pair

The headers that are specified to be included via <map> are <compare> (since C++20) and <initializer_list> (since C++11). Nothing more.

<map> may include other headers and thats one of the "implementation details" mentioned in comments. The part of the standard that explicitly allows standard headers to include others is [todo.put reference here].

The simple rule of thumb that avoids such headace is: Include what you use.


but throwing std::out_of_range is not an "implementation detail" - it is part of the specification of std::map!

Consider that this code compiles with gcc 10.2:

#include <map>

int main() {
    std::map<int, int> test;
    try {
        test.at(10);
    } catch(...) {
        return 1;
    }    
    return 0;
}

The out_of_range exception is thrown and catched, and 1 is returned. We know what at may throw and catch(...) will catch it, yet no include is needed for the exception.

On the other hand, the same compiler rejects your example, but compiles it when we add a seemingly unrelated header:

#include <map>
#include <sstream>    // why this? 

int main() {

    std::map<int, int> test;
    try {
        test.at(10);
    } catch(std::out_of_range& e) {
    }

    return 0;
}

However, this only works by coincidence. Apparently <sstream> does include <stdexcept> somewhere along the line. But this may change with compiler version or between differernt compilers.

like image 121
463035818_is_not_a_number Avatar answered Nov 10 '22 18:11

463035818_is_not_a_number


The implementation of std::map doesn't have to be all in the header file. Yes this is a class template, but it is free to use any internal non-template components.

Consequently, the header file doesn't have to mention std::out_of_range (it may well be hidden inside one of those non-template components) and so doesn't have to have its definition visible anywhere, or behave as if it includes <stdexcept>. It is explicitly allowed to, but there is no implicit or explicit obligation in the standard for it to do so. So it might, or might not.

In fact g++-9 behaves as if <map> includes <stdexcept>, and g++-10 does not, and in both cases they are correct.

like image 39
n. 1.8e9-where's-my-share m. Avatar answered Nov 10 '22 19:11

n. 1.8e9-where's-my-share m.


Why does std::map not include std::out_of_range

Assuming you are using GCC 10, GCC developers decided to optimize header dependencies in C++ Standard Library code. From Porting to GCC 10:

Header dependency changes

Some C++ Standard Library headers have been changed to no longer include the <stdexcept> header. As such, C++ programs that used components defined in <stdexcept> or <string> without explicitly including the right headers will no longer compile.

Previously components such as std::runtime_error, std::string and std::allocator were implicitly defined after including unrelated headers such as <array> and <optional>. Correct code should include the appropriate headers for the classes being used.

Also from GCC 10 Release Notes:

Reduced header dependencies, leading to faster compilation for some code.

like image 36
ks1322 Avatar answered Nov 10 '22 19:11

ks1322