简体   繁体   English

重载const运算符时使用const_iterator []

[英]Using const_iterator when overloading a const operator[]

I really do not understand what I am doing wrong below. 我真的不明白下面我在做什么错。 I have a class named Settings with the structure listed below, and two of the functions listed below as well. 我有一个名为Settings的类,具有下面列出的结构,以及下面列出的两个功能。 What I am having trouble with is specifically where to put the const modifiers when overloading a const operator[] within the overloading function. 我遇到的麻烦是,在重载函数内重载const运算符[]时,将const修饰符放在哪里。 Do I need to use const_cast somewhere? 我需要在某个地方使用const_cast吗? What am I missing? 我想念什么?

class Settings
{
    map<string, string> settingsMap;
    map<string, string>::const_iterator itc;

    const string getValue(string) const;

    public:
    const string operator[](string) const;
};

const string Settings::operator[](string K) const
{
    return getValue(K);
}


const string Settings::getValue(const string K) const
{
    const map<string, string> m = settingsMap;
    itc = m.begin();
    while(itc != m.end())
    {
        if(itc->first==K)
            return itc->second;
        itc++;
    }
    return 0;
}

Thanks in advance. 提前致谢。

If your function getValue() modifies the member itc, then it can't be const (unless itc is mutable). 如果您的函数getValue()修改了成员itc,则它不能是const(除非itc是可变的)。 I suggest you declare itc in the function getValue(): 我建议您在函数getValue()中声明itc:

...
const map<string, string> m = settingsMap;
imap<string, string>::const_iterator itc = m.begin();
...

the operator[] in c++ has two meanings: c ++中的operator []具有两个含义:
(1) a[i] = x; //store x into a in position i (1) a[i] = x; //store x into a in position i a[i] = x; //store x into a in position i
(2) x = a[i]; //load a in position i to x (2) x = a[i]; //load a in position i to x x = a[i]; //load a in position i to x

The first one must change the structure... and thus the structure cannot be const , so you should drop the last const for this: const string operator[](const string); 第一个必须更改结构...因此该结构不能为const ,因此您应为此删除最后一个const: const string operator[](const string); [note that the parameter in here is const string and not string , since it should probably not be changed. [请注意,此处的参数是const string而不是string ,因为它可能不应该更改。 in addition, since the output string shouldn't probably be changed, it should be defined as const as well. 另外,由于不应更改输出字符串,因此也应将其定义为const

The 2nd one, should probably return a string , and not a const string , so you should probably drop the first const : string operator[](const string) const; 第二个可能应该返回一个string ,而不是一个const string ,因此您应该删除第一个conststring operator[](const string) const; [since the original structure for this op is not changed, the last const is good and should remain]. [由于此操作的原始结构未更改,因此最后一个const很好,应该保留]。 In addition note the parameter is a const string and not a string , since you do not want to cahnge the parameter. 另外请注意,该参数是const string而不是string ,因为您不想更改该参数。

In your case: It seems you want the 2nd meaning for the operator[] , thus you should declare it as: string operator[](const string) const; 在您的情况下:似乎您想要operator[]的第二含义,因此应将其声明为: string operator[](const string) const;

Your problem is not with the const but with references. 您的问题不是const,而是引用。
Also your declarations in the class must match exactly the definitions you use when defining the functions. 同样,您在类中的声明必须与您在定义函数时使用的定义完全匹配。

class Settings
{
    map<string, string> settingsMap;
    map<string, string>::const_iterator itc;

    const& string getValue(const string& K) const; 
               //          ^^^^^  Added const to match definition below.
               //                 Also note the reference. This means you are referring
               //                 to the original value but because the reference is const
               //                 it cant be modified via this reference.

// ^^^^^^  This const means the returned value is const.
//         unless you return a reference this is meaningless. 
//         So also note the reference here are well.

                                 //         ^^^^^^  The last const means the method will
                                 //                 NOT change the state of any members. 

    public:
    const string&  operator[](const string&) const;
//  ^^^^^^^^^^^^^ As above return a const reference.
                          //  ^^^^^ As above pass parameters by const reference
                          //        otherwise it makes a copy of the parameter.
                                      //     ^^^^^  function will not change any members.
};

const string& Settings::operator[](const string& K) const  // Must match above definition.
{
    return getValue(K);
}


const string& Settings::getValue(const string& K) const
{
    const map<string, string> m = settingsMap;
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ As this is an object (not a reference)
//                                You are making a copy of the object into a local variable.
//                                This is probably not what you want.

    const map<string, string>& m = settingsMap; // This works.

    itc = m.begin();


    while(itc != m.end())
    {
        if(itc->first==K)
            return itc->second;
        itc++;
    }

    return 0;
 // ^^^^^^^^  This is not a good idea.
 //           It is creating a string from a NULL pointer (0 is convertible to pointer).
 //           What you really wanted to do is return a string. This is also why your
 //           return type was not working as you expected.

     static const string emptyResult;  // create a static object to use as the empty result
     return emptyResult;
}

In your declaration: 在您的声明中:

const string operator[](string K) const;

if you want just to read (and copy) the contents of the map, then the correct declaration should be: 如果您只想阅读(并复制)地图的内容,则正确的声明应为:

const string operator[](const string &k) const;

The return type should be const, otherwise you may be able to modify a temporary value, and this is not correct. 返回类型应为const,否则您可以修改临时值,这是不正确的。 The argument can be passed by const reference, since you are not modifying it. 可以通过const引用传递该参数,因为您没有对其进行修改。 With this declaration, the following two lines of code will give you an error: 使用此声明,以下两行代码将给您一个错误:

...
s["abc"] = "cde";   // cannot modify, the return type is const
s["abc"] += "efg";  // cannot modify, the return type is const

The const after the prototype declaration just tell you that operator[] does not modify the object, so it has to do with the code inside the method operator[] , and not about its usage. 原型声明后的const只是告诉您operator[]不会修改对象,因此它与方法operator[]的代码有关,而与它的用法无关。 For this reason, the const_iterator should be defined as local variable inside operator[] code. 因此, const_iterator应该在operator[]代码中定义为局部变量。

The const on the return type avoids the possibility that you modify a temporary value (the return type). 返回类型上的const避免了您修改临时值(返回类型)的可能性。 For efficiency, you can obtain the same result by returning a const reference. 为了提高效率,您可以通过返回const引用来获得相同的结果。

const string& operator[](const string &k) const;

Of course, if you want to modify the Settings container with operator[] , then you should return a non const reference. 当然,如果要使用operator[]修改“设置”容器,则应返回非const引用。

string& operator[](const string &k);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM