我有这堂课:
class MyClass {
public:
int operator[](const std::string&);
const std::string& operator[](const int&) const;
...
};
但是,如果我调用第二个运算符w / const literal 0:
,它会很有效MyClass myclass;
std::cout << myclass[0] << std::endl;
我收到了这个错误:
In function 'int main()':
ambiguous overload for 'operator[]' in 'myclass[0]'
note: candidates are:
note: const int MyClass::operator[](const string&)|
note: const string& MyClass::operator[](const int&) const
我想我明白了什么情况(0可以是字符串或int?),但我的问题是:有没有办法解决这个问题并保持运算符重载?
答案 0 :(得分:6)
致电MyClass::operator[](const std::string&)
涉及转换:
myclass
从MyClass&
到MyClass&
:完美匹配
0
到int
到const char*
的 std::string
:用户定义的转化
致电MyClass::operator[](const int&) const
涉及转换:
myclass
从MyClass&
到const MyClass&
:const qualified
0
从int
到int
:完美匹配
在这种情况下,当一个重载对于参数X“更好”但是对于参数Y不同的重载“更好”时,过载都不能被认为是最好的重载,并且编译器必须抱怨(假设没有第三个过载)打败了。)
是否可以将两个重载更改为const
或同时non-const
?如果没有,您可以添加第三个重载来处理这种情况:
const std::string& operator[](int n) {
return static_cast<const MyClass&>(*this)[n];
}
答案 1 :(得分:4)
0
不能是string
,但它可以是指针,这意味着它可以隐式转换到string
。请注意,其他常量积分不是这样,例如1
或42
- 只是0
。
4.10指针转换
1 /空指针常量是一个整数常量表达式(5.19) 整数类型的rvalue,其值为零。空指针常量 可以转换为指针类型;结果是空指针 该类型的值,可以与其他每个值区分开来 指向对象的指针或指向函数类型的指针。两个空指针值 同一类型应相等。空指针的转换 指向cv限定类型的指针的常量是单个转换,和 不是指针转换的顺序,后面是限定条件 转换(4.4)。
因此,在myclass[0]
的情况下,0
可以是int
或“空指针常量”。
标准还规定std::string
有一个非explicit
构造函数,它带有char
指针:
size_type find_last_not_of (const charT* s, size_type pos = npos) const;
现在,由于您的operator&
方法都采用const
引用类型的参数,因此可以传递临时值。这就是编译器混淆的原因 - 它不知道你想要哪一个 - 带int
的那个,或者通过string
构建临时string(const char*)
的那个
至于如何解决这个问题,我会后退一步。在我看来,你的两个operator[]
函数做了截然不同的事情。或者也许他们做同样的事情,给出不同的输入。如果他们做了不同的事情,那么我将提供具有不同(适当)名称的成员函数,并跳过尝试使用operator[]
语法。也许其中一个方法会返回一些真正被索引的东西 - 在这种情况下,我会使用operator[]
语法来表示那个,但只有那个。
如果他们确实做了同样的事情,并且那件事是通过索引返回一个项目,那么我只提供一个方法,并让它采用size_t
按价值。然后,您还可以提供某种转换功能(最好以免费的非会员功能的形式),例如,从string
转换为size_t
。这样做,您可以在string
:
myPos[str_to_index(str)];
答案 2 :(得分:3)
文字0
很特别。除了是八进制常量之外,它还可以转换为任何指针类型的空指针。这使得0
的{{1}}构造函数char const *
可用std::string
。
两个都不是更好的原因是因为运算符的int重载具有const
实例CV限定符。这样,两个重载都需要转换,同样糟糕。
明显的解决方法是明确要求const重载:
static_cast<MyClass const &>(myclass)[0]