错误 C2679:二进制"[":未找到采用类型为"const VerseKey"的右操作数的运算符(或者没有可接受的转换)



我正在尝试使函数调用(*this)[newVerseKey] = newVerse;那是我收到错误的时候。我的程序正在从模板制作地图。地图在地图中定义。我有一个名为 bible 的类,它继承自 map 类,所以 Bible"是"一个地图。导致我的 Bible 对象的构造函数出现问题的代码。我正在从文本文件中读取经文、章节和文本,并从该数据创建 VerseKey 和 Verse 类对象。函数调用 (*this)[newVerseKey] = newVerse;应该采用 VerseKey 对象和 Verse 对象并将值分配给地图。我已经在我的 Map.hpp 文件中重载了 = 运算符。我正在使用地图内的包装器来保存我的数据。

这是我的圣经.cpp(函数调用发生的地方)

#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()
{
}

这是我的设置函数。它应该采用两种数据类型并分配正确的键和值类型。我收到该行的错误:键[键] = 值;

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];
    }

这是运算符[]

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;
    }

这是我的整个地图.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;
    }
}

如果您需要更多代码,请告诉我。

A. 您的Map<KeyType, ValueType>::Wrapper对象必须在映射中实现operator=(const ValueType &value)设置值

b. 返回ValueType&而不是Map<KeyType, ValueType>::Wrapper operator[]

相关内容

最新更新