我正在尝试调用函数(* 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;
}
}
如果您需要更多代码,请与我们联系。
答案 0 :(得分:-1)
:
一个。您的Map<KeyType, ValueType>::Wrapper
对象必须在地图中实现operator=(const ValueType &value)
设置值
湾在ValueType&
Map<KeyType, ValueType>::Wrapper
而不是operator[]