Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 解决运算符[]的不明确重载_C++_Operators_Operator Overloading - Fatal编程技术网

C++ 解决运算符[]的不明确重载

C++ 解决运算符[]的不明确重载,c++,operators,operator-overloading,C++,Operators,Operator Overloading,我有这门课: 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]

我有这门课:

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;

我想我了解情况(0可以是字符串或int?),但我的问题是:有没有办法解决这个问题并保持运算符重载?

文本
0
是特殊的。除了作为一个八进制常量外,它还可以转换为任何指针类型的空指针。这使得
0
对于
std::string
char const*
-构造函数是可行的

这两种重载都不好的原因是运算符的int重载具有
const
实例CV限定符。这样一来,两个重载都需要转换,并且同样糟糕

显而易见的解决方法是明确要求常量重载:

static_cast<MyClass const &>(myclass)[0]
static_cast(myclass)[0]

调用
MyClass::operator[](const std::string&)
涉及转换:

myclass
myclass&
myclass&
:完美匹配

0
int
const char*
std::string
:用户定义的转换


调用
MyClass::operator[](const int&)const
涉及转换:

myclass
myclass&
const myclass&
:const限定

0
int
int
:完美匹配

在这种情况下,当一个重载对参数X“更好”,而另一个重载对参数Y“更好”时,两个重载都不能被视为最佳重载,编译器必须抱怨(假设没有第三个重载比这两个重载都好)

是否可以将两个重载同时更改为
常量
或同时更改为
非常量
?如果没有,您可以添加第三个重载来处理这种情况:

const std::string& operator[](int n) {
    return static_cast<const MyClass&>(*this)[n];
}
const std::字符串和运算符[](int n){
返回静态_cast(*this)[n];
}

0
不能是
字符串
,但它可以是指针,这意味着它可以隐式转换为
字符串
。请注意,对于其他常数积分,如
1
42
,这是不正确的,特别是
0

4.10指针转换

1/空指针常量是整型常量表达式(5.19) 计算结果为零的整数类型的右值。空指针常量 可以转换为指针类型;结果是空指针 该类型的值,并可与 指向对象的指针或指向函数类型的指针。两个空指针值 同一类型的应进行同等比较。空指针的转换 指向cv限定类型指针的常量是单个转换,并且 不是指针转换后的限定顺序 转换(4.4)

因此,在
myclass[0]
的情况下,
0
可以是
int
或`空指针常量

该标准还规定,
std::string
具有非
显式
构造函数,该构造函数采用
char
指针:

size_type find_last_not_of (const charT* s, size_type pos = npos) const;
现在,由于您的
操作符和
方法都采用
const
引用类型的参数,因此可以将它们传递给临时变量。这就是为什么编译器会感到困惑的原因——它不知道您想要哪一个——接受
int
的编译器,还是接受通过
string(const char*)
构造的临时
字符串的编译器

至于如何解决这个问题,我会退后一步。在我看来,您的两个
操作符[]
函数做的事情截然不同。或者他们做同样的事情,给予不同的输入。如果它们做不同的事情,那么我将提供具有不同(适当)名称的成员函数,并跳过尝试使用
运算符[]
语法。也许其中一个方法返回的是真正被索引的东西——在这种情况下,我会使用
操作符[]
语法来表示这个方法,但仅限于那个方法

如果他们真的做了同样的事情,那就是按索引返回一个项目,那么我只提供一种方法,让它按值取
size\u t
。然后,您还可以提供某种转换函数(最好是以自由、非成员函数的形式),将字符串转换为大小。这样,在通过
字符串编制索引时,您可以这样编写代码:

myPos[str_to_index(str)];

为什么要费心于
const int&
?只需取一个
int
字符串
版本匹配,因为常量文本零可以隐式转换为null
const char*
指针,然后从那里转换为
std::string
。仍在考虑如何避免这种情况。我很惊讶这些被认为是相等的秩转换。返回
const int
很奇怪(而且毫无意义)。@sftrabbit:这是实例上
const
限定的原因。没有它,一个会是一个更好的超载。谢谢!现在,我只是删除了
const
CV限定符作为解决方法。对于那些感到困惑的人,这里有两个参数:this指针和括号内的参数。运算符的第一个版本不要求第一个参数进行转换,第二个参数先进行int到指针的转换,然后再进行用户定义的转换。运算符的第二个版本要求对第一个参数进行常量转换,而对第二个参数不进行转换。所以第一个版本在第一个参数上更好,第二个版本在第二个参数上更好。由于两者对于所有参数都不相同或更好,因此它的模糊const限定转换是标准转换,而字符串(0)是用户定义的转换,因此没有歧义。谢谢!正如我在给Ker的评论中提到的
myPos[str_to_index(str)];