错误C2679:二进制'[':找不到运算符,它接受'const VerseKey'类型的右手操作数(或者没有可接受的转换)

时间:2016-03-17 03:43:57

标签: c++

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

这是我的Bible.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()
{
}

这是我的设定功能。它应该采用两种数据类型并分配正确的键和值类型。我在行上收到错误: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];
    }

这是运营商[]

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

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

如果您需要更多代码,请与我们联系。

1 个答案:

答案 0 :(得分:-1)

一个。您的Map<KeyType, ValueType>::Wrapper对象必须在地图中实现operator=(const ValueType &value)设置值

湾在ValueType&

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