Does anyone know what the following compilation warning: catching polymorphic type ‘class std::out_of_range’ by value [-Wcatch-value=]
warning means and how to correct it? I copied this code block literally out of Stroustrup's C++ 4th Edition. Thank you
#include <iostream>
#include <vector>
#include <list>
using std::vector;
using std::list;
using std::cout;
template <typename T>
class Vec : public vector<T> {
public:
using vector<T>::vector; // constructor
T& operator[](int i) { return vector<T>::at(i); }
const T& operator[](int i) const { return vector<T>::at(i); }
};
int main(int argc, char* argv[]) {
vector<int> v0 = {0, 1, 2};
Vec<int> v1 = {0, 1, 2};
cout << v0[v0.size()] << '\n'; // no error
try {
cout << v1[v1.size()]; // out of range
} catch (std::out_of_range) {
cout << "tried out of range" << '\n';
}
return 0;
}
Error:
$ g++ -Wall -pedantic -std=c++11 test69.cc && ./a.out
test69.cc: In function ‘int main(int, char**)’:
test69.cc:32:17: warning: catching polymorphic type ‘class std::out_of_range’ by value [-Wcatch-value=]
} catch (std::out_of_range) {
^~~~~~~~~~~~
0
tried out of range
You should modify that to
catch (std::out_of_range const&)
The message is warning you that polymorphism only works with references and pointers.
If you look at the C++ Core Guidelines, you can find
E.15: Catch exceptions from a hierarchy by reference
This is exactly your case. By catching a value, you are effectively using just the base class of the exception thrown (regardless of the type actually thrown). Instead, catch by reference (or const reference, if you don't plan on modifying the exception), to retain the polymorphic behaviour.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With