Vector::At VS. Vector::Operator[]

vector::at vs. vector::operator[]

I'd say the exceptions that vector::at() throws aren't really intended to be caught by the immediately surrounding code. They are mainly useful for catching bugs in your code. If you need to bounds-check at runtime because e.g. the index comes from user input, you're indeed best off with an if statement. So in summary, design your code with the intention that vector::at() will never throw an exception, so that if it does, and your program aborts, it's a sign of a bug. (just like an assert())

What is the difference between the vector operator [] and at()

The MyVector is a pointer to a vector, not a vector.

Two solutions:

  1. Since MyVector is a pointer, you need to dereference the pointer
    first to get back the vector.

    (*MyVector)[i]
  2. Less used: Use the operator keyword:

    MyVector->operator[](i)

Should I use std::vector::at() in my code

If you have reason to believe that the index is not in your control, or if the control flow is particularly complicated and you're tracing bugs, then you might want to use at() during the debug phase, but never inside loops or any situation where you know that the index is safe.

Even in other situations you should either prevalidate the index (e.g. if it's user input), or if you are just getting the value from a complicated algorithm, use assert and fix the bug if there is one. [Edit.] Or perhaps if you are writing a very complicated algorithm and you aren't sure that all your indices are always valid, you could use at() inside that algorithm and put the call into a try block -- but even here it is preferable to be offensive and use with assertions.[/]

Personally, I can't see any good reasons for at() to survive into release code. You could possibly contrive some examples where you want to use exception handling as a convenient way to direct your control flow, but any such use case would be very situational.

Why is std::vector::operator[] 5 to 10 times faster than std::vector::at()?

The reason is that an unchecked access can probably be done with a single processor instruction. A checked access will also have to load the size from memory, compare it with the index, and (assuming it's in range) skip over a conditional branch to the error handler. There may be more faffing around to handle the possibility of throwing an exception. This will be many times slower, and this is precisely why you have both options.

If you can prove that the index is within range without a runtime check then use operator[]. Otherwise, use at(), or add your own check before access. operator[] should be more or less as fast as possible, but will explode messily if the index is invalid.

Convert between vector::operator[] and vector::at in C++

Like

If (DEBUG)
{
// Do with .at
}
else
{
// Do with []
}

You get something like this by using operator[] and by enabling bounds checking debug mode of the standard library implementation that you use. How to do that, and whether that option exists depends on what implementation you use.

Note that typically the entire project, including all libraries must have been built with the same standard library options. This is a potential problem if you use pre-built libraries.

A universally portable solution is to write a wrapper function that conditionally calls one function or the other depending on build configuration. Downside is that this requires changing all code using the wrapped function to use the custom one.

C++ Vector at/[] operator speed

You can use a reference:

int &curr = myvec.at(i);
// do stuff with curr

The at member function does bounds checking to make sure the argument is within the size of the vector. Profiling is only way to know exactly how much slower it is compared to operator[]. Using a reference here allows you to do the lookup once and then use the result in other places. And you can make it a reference-to-const if you want to protect yourself from accidentally changing the value.

vector::push_back vs vector::operator[]

push_back creates a new element on the back with the value specified. operator[] requires the element to be there; it just accesses it. The reason [5] doesn't work is because you have 5 elements, so your indices range from 0 to 4.

Generally, when adding new elements, push_back is preferred over resize, followed by operator[]. Only one can be used for reading, though, and operator[] is also needed to maintain normal array syntax.

Vector and []-operator overloading

You'd need to return a reference to your element - however note that even if you did, you'd run into inifinite recursion - your operator[] calls itself.

Either way - inheriting from std::vector isn't a good idea. Use composition instead.

Why isn't vector::operator[] implemented similar to map::operator[]?

Quite simply: Because it doesn't make sense. What do you expect

std::vector<int> a = {1, 2, 3};
a[10] = 4;

to do? Create a fourth element even though you specified index 10? Create elements 3 through to 10 and return a reference to the last one? Neither would be particularily intuitive.

If you really want to fill a vector with values using operator[] instead of push_back, you can call resize on the vector to create the elements before settings them.

Edit: Or, if you actually want to have an associative container, where the index is important apart from ordering, std::map<int, YourData> might actually make more sense.



Related Topics



Leave a reply



Submit