3
\$\begingroup\$

The problem:

std::vector and other containers have two functions for accessing / modifying their content: operator[] and at().

at() is meant for debugging, to catch out-of-bound bugs. However, at() is also quite a lot slower than operator[]. Both above facts would yearn for a way to switch between the use of at() and operator[] based on whether it is a debug build or a production build, especially if performance matters.

However, I can see no such easy way. Sadly standard containers don’t offer a flag or sth that would allow to do this.

I tried to write a simple wrapper that would switch between at() and operator[] based on whether or not NDEBUG is defined, in line with how the assert macro works.

Note: This is a different solution to the same problem as stated here: Allowing switching between operator[] and at() based on NDEBUG This solves the issue of 2d arrays. But I wanted to post two solutions, 'cuz I feared You could frown upon such a macro :(

The code:

// AOO = At Or Operator[]
#ifndef NDEBUG
  #define AOO(INDEX) .at(INDEX)
#else
  #define AOO(INDEX) [INDEX]
#endif

The use:

void testNormalUse()
{
    std::vector<int> vec(100);
    vec AOO(50) = 5;
    std::cout << vec AOO(50) << std::endl;
}

void testRequireConst()
{
    const std::vector<int> vec(100, 5);
    std::cout << vec AOO(50) << std::endl;
}

void testRvalueRef()
{
    std::vector<int>vec(100, 5);
    std::cout << std::move(vec) AOO(50) << std::endl;
}

void test2d()
{
    std::vector<std::vector<int>> vec(100, std::vector<int>(100, 5));
    std::cout << vec AOO(50) AOO(50) << std::endl;
}

int main() {
    testNormalUse();
    testRequireConst();
    testRvalueRef();
    test2d();
}

Ideone

Of course I know this is weird syntax. But the non-macro solution brings up pain with multidimensional arrays, a problem the macro version solves.

If only macros allowed punctuation, then we could make it look operator-like. But alas, they don't.

\$\endgroup\$
  • \$\begingroup\$ Possible duplicate of Allowing switching between `operator[]` and `at()` based on `NDEBUG` \$\endgroup\$ – πάντα ῥεῖ Mar 17 '17 at 21:55
  • \$\begingroup\$ @πάνταῥεῖ Is it forbidden on this site to post two substantially different solutions to same problem? \$\endgroup\$ – gaazkam Mar 17 '17 at 21:57
  • 1
    \$\begingroup\$ Forbidden? No. But it's considered good practice to declare what you did and why to help the reviewers understand why you did what you did. The usual approach though, is posting both pieces of code in the same question and tag as comparative-review. \$\endgroup\$ – Mast Mar 18 '17 at 9:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.