This question already has an answer here:
During active development of a class that uses std::vector
, it often happens that an index is out of bounds. (See this code review question for a practical example.) When using operator[]
, this results in undefined behavior. Still, the []
syntax is easy to read an more convenient than writing .at()
.
Therefore I'd like to write my code using the []
operator, but at the same time have bounds checks enabled. After testing the code, it should be very easy to remove the bounds checks.
I'm thinking of the following code:
util::bound_checked<std::vector<int>> numbers;
numbers.push_back(1);
numbers.push_back(2);
numbers.push_back(3);
numbers.push_back(4);
std::cout << numbers[17] << "\n";
To me, this utility template seems to be so straight-forward that I'd expect it to exist. Does it? If so, under which name?
To me, this utility template seems to be so straight-forward that I'd expect it to exist
For gcc it does exist. gcc libstdc++ has a set of debug containers. For std::vector
it has __gnu_debug::vector
debug container. See documentation.
I don't think anything like this exists, but it's fairly easy to create:
template <class Container>
struct bound_checked : public Container
{
using Container::Container;
auto operator[] (typename Container::size_type i) -> decltype(this->at(i))
{ return this->at(i); }
auto operator[] (typename Container::size_type i) const -> decltype(this->at(i))
{ return this->at(i); }
};
Note that the above actually uses a discouraged practice, namely public inheritance from standard containers (which are not designed for it). My understanding of your question was that this wrapper would be used in testing purposes only, which is fine. However, if you want this to remain in production and want to be on the very safe side, use non-public inheritance:
template <class Container>
struct bound_checked : private Container
{
using Container::Container;
auto operator[] (typename Container::size_type i) -> decltype(this->at(i))
{ return this->at(i); }
auto operator[] (typename Container::size_type i) const -> decltype(this->at(i))
{ return this->at(i); }
using Container::begin;
using Container::end;
using Container::at;
using Container::insert;
// ... you get the idea
};
If you use GCC (or MinGW) with libstdc++, #define _GLIBCXX_DEBUG
will do what you want.
Or even better, define it with a flag: -D_GLIBCXX_DEBUG
.
Does it? If so, under which name?
I'm pretty sure it does exist. Many compilers enable std::vector<T>::at()
as implementation for std::vector::operator[]()
if a compiler intrinsic __DEBUG
building macro is enabled.
Therefore I'd like to write my code using the [] operator, but at the same time have bounds checks enabled. After testing the code, it should be very easy to remove the bounds checks.
Regarding the naming, I'd say that's debug vs. release building. The checks will be removed when the code is compiled without the __DEBUG
definition.
来源:https://stackoverflow.com/questions/48035379/automatically-check-bounds-in-stdvector