2012-03-09 80 views
2

我与这些运营商(鉴于某些类型的T)一个structC++:在哪种情况下将使用哪个运算符[]?

T& operator[](size_t i) { return write(i); } 
const T& operator[](size_t i) const { return get(i); } 

当我通过[i]访问的这一个非const对象,将它总是使用非const operator[]还是会自动看到哪一个是必要的(例如,如果const版本“足够”)并采取那一个?那里有什么规则?大多数编译器(我主要关心Clang,最近的GCC和最近的MSVC)在那里的表现都一样吗?

背景:write(i)可能比get(i)昂贵得多。我甚至有一些代码的行为稍有不同,其中write(i)可能会触及一些文件,设置一些修改标志或其他。

回答

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重载并且实例参数是非常量,那么选择非常量版本是因为它需要零转换,而const过载将需要一次(标准)转换,即从T &T const &,因此该过载不如非常量适合。

+0

+1根据转换解释 – je4d 2012-03-09 23:09:11

3

如果您有一个非const对象,它将始终使用非常量重载。

如果你想手动控制它,使用const_cast ......虽然,如果方法有不同的行为,你想清楚你在做什么,它可能会更好调用名为方法来代替。

相关问题