我经常遇到索引超出范围的错误,如果我使用.at()
而不是[]
来访问向量或字符串中的元素,则很容易捕获到索引错误。但是,at()
由于边界检查而使我的程序速度降低了5倍。
我正在尝试编写一种宏,用这种方式将.at(someVariable)
替换为[someVariable]
,我可以取消对该宏的注释,而不必手动用.at()
替换每个[]
。我已经阅读了cppreference.com上有关宏的文档,但似乎无法设计一种获得此功能的方法。
答案 0 :(得分:12)
通常,我会避免使用此类宏,因为它们是“不可见的”(因此,对语义不了解的人来说,更改后的语义会被巧妙地隐藏起来),并且可以更改实际上期望at
的代码的功能甚至在发行版本中也超出范围。如果有的话,我会定义一些引人注目的东西,例如全大写的AT
。
幸运的是,实际上并不需要这样做,因为“三大” C ++运行时已经具有内置功能,可以有条件地对operator[]
进行边界检查(这也具有比at
更具可读性的优点):
-D_GLIBCXX_DEBUG
,则会得到the debug version of STL containers,它对operator[]
执行边界检查,以及对迭代器的许多其他调试检查; _LIBCPP_DEBUG
to 1; ITERATOR_DEBUG_LEVEL
设置为2
(并且在调试版本中默认已启用)。顺便说一下,其中某些错误(实际上溢出了分配大小的错误,而不仅仅是向量的“逻辑上有效”的大小)也可以使用address sanitizer(-fsanitize=address
在gcc和clang)或valgrind(慢!)和类似工具。
答案 1 :(得分:7)
这是不涉及宏的一种方法-为方便起见,它使用了c ++ 17的<script>
import { mapFieldsPrefixed } from './vuex-map-fields-prefixed';
const prefix = "'addresses[' + this.idx + '].'"
const fields = [
"town"
]
export default {
name: 'my-component',
props: ['idx'],
computed: {
...mapFieldsPrefixed(prefix, fields)
}
}
</script>
:
if constexpr
答案 2 :(得分:4)
您可以使用数组取消引用运算符的全名:
#define at(x) operator[](x)
(x)
部分不是必不可少的,但是只有在后面跟有参数的情况下才替换at
,而不是单独替换单词。您还需要在包含所有标准标头的之后进行定义,或者将它替换具有它的类中的at
成员函数声明,从而导致编译错误。