我有struct
这些运算符(给定某种类型T
):
T& operator[](size_t i) { return write(i); }
const T& operator[](size_t i) const { return get(i); }
当我通过[i]
访问它的非const对象时,它是否总是使用非const operator[]
或者它会自动查看需要哪一个(例如,如果const-version是“够了”)拿那个?有什么规则?并且大多数编译器(我主要关心的是Clang,最近的GCC和最近的MSVC)在那里表现相同吗?
背景:write(i)
可能比get(i)
贵得多。我甚至有一些行为略有不同的代码,其中write(i)
可能触及某些文件,设置一些修改标志或其他。
答案 0 :(得分:4)
与任何成员函数一样,重载的选择取决于隐式实例参数的类型:
T x;
x.foo(); // #1
const_cast<T const &>(x).foo(); // #2
在#1的情况下,隐式实例参数的类型为T
,因此重载T::foo()
是可行的并且将被选中。在#2的情况下,隐式实例参数具有类型T const
,因此只有重载T::foo() const
是可行的,并且如果它存在则将被选中。
正常的重载决策规则在这里起作用:如果你有const和非const重载并且instance参数是非常量的,那么选择非常量版本是因为它需要零转换,而const过载需要一个(标准)转换,即从T &
到T const &
,因此重载不如非常规转换。
答案 1 :(得分:3)
如果你有一个非const对象,它将始终使用非const重载。
如果您想手动控制它,请使用const_cast
...但是,如果这些方法有不同的行为,并且您想清楚地知道您正在做什么,那么调用a可能会更好改为命名方法。