C ++宏,用[]

时间:2019-04-06 00:29:10

标签: c++

我经常遇到索引超出范围的错误,如果我使用.at()而不是[]来访问向量或字符串中的元素,则很容易捕获到索引错误。但是,at()由于边界检查而使我的程序速度降低了5倍。

我正在尝试编写一种宏,用这种方式将.at(someVariable)替换为[someVariable],我可以取消对该宏的注释,而不必手动用.at()替换每个[]。我已经阅读了cppreference.com上有关宏的文档,但似乎无法设计一种获得此功能的方法。

3 个答案:

答案 0 :(得分:12)

通常,我会避免使用此类宏,因为它们是“不可见的”(因此,对语义不了解的人来说,更改后的语义会被巧妙地隐藏起来),并且可以更改实际上期望at的代码的功能甚至在发行版本中也超出范围。如果有的话,我会定义一些引人注目的东西,例如全大写的AT

幸运的是,实际上并不需要这样做,因为“三大” C ++运行时已经具有内置功能,可以有条件地对operator[]进行边界检查(这也具有比at更具可读性的优点):

顺便说一下,其中某些错误(实际上溢出了分配大小的错误,而不仅仅是向量的“逻辑上有效”的大小)也可以使用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成员函数声明,从而导致编译错误。