简体   繁体   中英

error C2679: binary '[' : no operator found which takes a right-hand operand of type 'const VerseKey' (or there is no acceptable conversion)

I am trying to make the function call (*this)[newVerseKey] = newVerse; an that is when I receive the error. My program is making a map from a template. The map is defined at Map. I have a class named bible that inherits from the map class so Bible "is" a Map. The code that is causing the problem in the constructor for my Bible object. I am reading in the verse, chapter, and text from a text file and making a VerseKey and Verse class objects from that data. The function call (*this)[newVerseKey] = newVerse; is supposed to take the VerseKey object and Verse object and assign the values to the map. I have overloaded the = operator in my Map.hpp file. I am using a wrapper that is inside my map to hold my data.

Here is my Bible.cpp (where the function call takes place)

#include "Bible.h"

Bible::Bible()
{
    ifstream inputFile;
    inputFile.open("Bible1Verse.txt");
    if (!inputFile)
    {
        cout << "File could not be found" << endl;
        exit(1);
    }
    int verseNumber, chapterNumber;
    string verseText, line, bookName;
    VerseKey newVerseKey;
    Verse newVerse;

    getline(inputFile, line);

    while (line != "")
    {
        istringstream iss(line);
        if (line[0] != 'B')
        {
            iss >> chapterNumber;
            iss >> verseNumber;
            getline(iss, verseText);

            newVerseKey.book = bookName;
            newVerseKey.chapter = chapterNumber;
            newVerseKey.verseNumber = verseNumber;

            newVerse.verseKey = newVerseKey;
            newVerse.verseText = verseText;

            (*this)[newVerseKey] = newVerse;
        }
        else
        {
            string junk;
            iss >> junk >> junk;
            getline(iss, bookName);
        }
        getline(inputFile, line);
    }
}


Bible::~Bible()
{
}

Here is my set function. It is supposed to take the two data types and assign the correct key and value types. I receive the error on the line: keys[key] = value;

template <typename KeyType, typename ValueType>
    ValueType* Map<KeyType, ValueType>::set(const KeyType &key,const ValueType &value)
    {
        //if the key is already in the keys list,
        //change the value corresponding to that key value passed to this method

        if (find(key) != NULL)
        {
            keys[key] = value;
        }
        //if the key is NOT in the list, add it and the value to the end of their lists
        else
        {
            keys.push_back(key);
            values.push_back(value);
        }
        // return the address of the value, in the values list, that was changed or added

        return &values[0];
    }

Here is the operator[]

template <typename KeyType, typename ValueType>
    typename Map<KeyType, ValueType>::Wrapper Map<KeyType, ValueType>::operator[](const KeyType& key)
    {
        //return a Wrapper object that has a reference to this Map and the key that was passed in
        Wrapper result(*this, key);
        return result;
    }

Here is my whole map.hpp

#include <vector>
#include <string>
#include <stdexcept>
using std::range_error;
using std::string;

namespace util
{
    template <typename KeyType, typename ValueType>
    class Map
    {

    public:
        // Wrapper is an inner class of the Map Template
        class Wrapper
        {
        public:
            //this is a type cast operator that can be used to cast an object
            //of type Wrapper to an object of type ValueType
            operator ValueType&();
            ValueType* operator &();
            const ValueType& operator =(const ValueType& rValue);

        private:
            Wrapper(Map &map, const KeyType &key);
            Wrapper(const Wrapper & value);
            Map& map;
            KeyType key;
            ValueType* value;

            friend class Map;
        };
        Wrapper operator[](const KeyType& key);
        unsigned size();

    private:
        std::vector<KeyType> keys;
        std::vector<ValueType> values;

        ValueType* find(const KeyType &key);
        ValueType* set(const KeyType &key,const ValueType &value);
    };

    /*==========================================================================
    * Map class methods
    */

    template <typename KeyType, typename ValueType>
    typename Map<KeyType, ValueType>::Wrapper Map<KeyType, ValueType>::operator[](const KeyType& key)
    {
        //return a Wrapper object that has a reference to this Map and the key that was passed in
        Wrapper result(*this, key);
        return result;
    }

    template <typename KeyType, typename ValueType>
    unsigned Map<KeyType, ValueType>::size()
    {
        //return the number of items that are in the keys or values list
        return keys.size();
    }

    template <typename KeyType, typename ValueType>
    ValueType* Map<KeyType, ValueType>::find(const KeyType &key)
    {
        //loop through the keys list to see if the key parameter is in the list
        for (size_t i = 0; i < keys.size(); i++)
        {
        //  //if the key is in the list, return the address of the value at that same
        //  //index in the values list
            if (keys[i] == key)
            {
                return &values[i];
            }
        //  //if the key is NOT in the list, return NULL
        }
        return NULL;
    }

    template <typename KeyType, typename ValueType>
    ValueType* Map<KeyType, ValueType>::set(const KeyType &key,const ValueType &value)
    {
        //if the key is already in the keys list,
        //change the value corresponding to that key value passed to this method

        if (find(key) != NULL)
        {
            keys[value] = value; // i changed value to key
        }
        //if the key is NOT in the list, add it and the value to the end of their lists
        else
        {
            keys.push_back(key);
            values.push_back(value);
        }
        // return the address of the value, in the values list, that was changed or added

        return &values[key]; // i changed 0 to key
    }

    /*==========================================================================
    * Wrapper methods
    */

    template <typename KeyType, typename ValueType>
    Map<KeyType, ValueType>::Wrapper::Wrapper(Map &map, const KeyType &key) :map(map), key(key) //Wrapper Constructor
    {
        //in the member initialization list - set the map and the key members to
        //the values passed to the constructor

        //in the body of the constructor - set the value member to the
        //map's value with that key. Hint: use map.find()

        value = map.find(key);
    }

    //Copy constructor
    template <typename KeyType, typename ValueType>
    Map<KeyType, ValueType>::Wrapper::Wrapper(const Wrapper& rValue) : map(rValue.map), key(rValue.key), value(rValue.value)
    {
        //in the member initialization list - set the map, the key, and the value
        //members to the values passed to the constructor
    }

    //conversion operator, from a Wrapper to a ValueType
    template <typename KeyType, typename ValueType>
    Map<KeyType, ValueType>::Wrapper::operator ValueType&()
    {
        //if the value is null throw an std::range_error exception
        //with the text "Key not found in map"
        //stdexcept is included for this purpose

        //value is always NULL at this moment

        if (value == NULL)
        {
            throw range_error("Key not found in map");
        }

        //if the value is not null return the value (dereferenced)
        else
        {
            return *(value);
        }
    }

    //address of operator. This is used when the programmer tries to 
    //find the address of a Wrapper object.  We return the address of the
    //value inside the wrapper instead.

    template <typename KeyType, typename ValueType>
    ValueType* Map<KeyType, ValueType>::Wrapper::operator &()
    {
        //if the value is null throw an std::range_error exception
        //with the text "Key not found in map"
        //stdexcept is included for this purpose

        if (value == NULL)
        {
            throw range_error("Key not found in map");
        }
        else
        {
            return value;
        }

        //if the value is not null return the value pointer
    }

    //assignment operator.  This is used when a wrapper is the l-value in an assignment 
    //and the r-value is of type ValueType
    template <typename KeyType, typename ValueType>
    const ValueType& Map<KeyType, ValueType>::Wrapper::operator =(const ValueType& rValue)
    {
        // if the value member is null
        // set the map's value for the current key to the value parameter (use map.set)
        // set the value member of the wrapper to the rValue (you can use the value returned from map.set)
        if (value == NULL)
        {
            ValueType * temp;
            temp = map.set(key, rValue);
            value = temp;
        }


        //if the value member is NOT null
        //set the member value to the value parameter
        //(you will need to dereference the member value to make this assignment)
        else
        {
            *value = rValue;
        }

        //return the rValue parameter
        return rValue;
    }
}

If you need more code, let me know.

either:

a. your Map<KeyType, ValueType>::Wrapper object has to implement operator=(const ValueType &value) setting value in the map

b.return ValueType& instead of Map<KeyType, ValueType>::Wrapper in operator[]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

Related Question Error:C2679 binary '==': no operator found which takes a right-hand operand of type 'const std::string' (or there is no acceptable conversion Error C2679: binary '>>' : no operator found which takes a right-hand operand of type 'const char [4]' (or there is no acceptable conversion) 22 C2679 binary '-=': no operator found which takes a right-hand operand of type 'T' (or there is no acceptable conversion) Error 2 error C2679: binary '/' : no operator found which takes a right-hand operand of type (or there is no acceptable conversion) error C2679: binary '<<': no operator found which takes a right-hand operand of type 'mystring' (or there is no acceptable conversion) error C2679: binary '>' : no operator found which takes a right-hand operand of type 'int' (or there is no acceptable conversion) error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'Rectangle' (or there is no acceptable conversion) c++ error c2679: binary '[' : no operator found which takes a right-hand operand of type 'SalesItem' (or there is no acceptable conversion) Error 1 error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'rational' (or there is no acceptable conversion) error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::vector<_Ty> *' (or there is no acceptable conversion)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM