Ключ std :: map не найден, хотя записи идентичны

132
11

Я изучаю C++ и пишу оболочку для std :: map и std :: string, и я наткнулся на проблему. Всякий раз, когда я добавляю что-то на карту, используя строку в качестве ключа, когда я пытаюсь получить доступ к этому элементу, используя точно такой же ключ, он говорит, что ключ находится за пределами карты. Вот мой код (не относящиеся к делу части):

ADictionary.h

#ifndef ADICTIONARY_H
#define ADICTIONARY_H

#include <map>

...

template<typename KEY, typename VALUE>
class ADictionary {
public:
...

VALUE operator [](KEY key) const {
return value.at(key);
}

void add(KEY key, VALUE value) {
this->value.insert(std::make_pair(key, value));
}

...

private:
std::map<KEY, VALUE> value;
};

#endif

AString.cpp

#include "AString.h"

AString::AString() {
value = "";
}

AString::AString(const char character) {
value = character;
}

AString::AString(const char * characters) {
value = characters;
}

AString::AString(std::string text) {
value = text;
}

...

AString::operator const char *() const {
return value.c_str();
}

AString::operator const std::string() const {
return value;
}

...

ABoolean AString::operator<(AString & text) const {
return getLength() < text.getLength();
}

ABoolean AString::operator>(AString & text) const {
return text < *this;
}

ABoolean AString::operator==(AString & text) const {
return value == text.value;
}

ABoolean AString::operator!=(AString & text) const {
return !(text == *this);
}

AString & AString::operator=(AString & text) {
value = text.value;

return *this;
}

...

The code which uses the above

ADictionary<AString, AString> test;
AString a = "a";
AString b = "b";
test.add(a, b);
std::cout << test[a]; // Error occurs here, according to the program "a" is not a key in the map

Я надеюсь, что кто-то может объяснить мне, что происходит не так. Я попытался создать словарь со стандартным std :: string в качестве типов, и он работал правильно:

ADictionary<std::string, std::string> test;
std::string a = "a";
std::string b = "b";
test.add(a, b);
std::cout << test[a]; // No error this time

Как я уже сказал, я довольно новичок в C++, поэтому могут быть и другие ошибки. Если это так, не стесняйтесь указывать на них.

Спасибо!

РЕДАКТИРОВАТЬ:

AString.h

#ifndef ASTRING_H
#define ASTRING_H

#include <string>

#include "ABoolean.h"
#include "AInteger.h"
#include "AList.h"

class ABoolean;
class AInteger;
template<typename VALUE>
class AList;

class AString {
public:
AString();
AString(const char);
AString(const char *);
AString(std::string);
~AString();

operator const char *() const;
operator const std::string() const;
operator const AInteger() const;

ABoolean operator<(AString &) const;
ABoolean operator>(AString &) const;
ABoolean operator==(AString &) const;
ABoolean operator!=(AString &) const;
AString & operator=(AString &);
AString & operator+(AString &);
AString & operator+=(AString &);

void clear();
ABoolean contains(AString) const;
AInteger getIndex(AString) const;
AInteger getLength() const;
AList<AString> getSplit(AString) const;
AString getSubstring(AInteger, AInteger) const;
void removeRange(AInteger, AInteger);
void removeSubstring(AString);
void toLowercase();
void toUppercase();

private:
std::string value;
};

AString & operator+(const char, AString &);
AString & operator+(const char *, AString &);

#endif

спросил(а) 2021-01-25T22:07:41+03:00 4 месяца, 2 недели назад
1
Решение
100

Ваши строковые операторы кажутся неверными.

В std :: map по умолчанию используется оператор less than. Пока вы предоставляете один для AString, единственное, что он делает, это проверяет длину строки. Что если две строки имеют одинаковую длину?

Правильнее всего сделать лексикографическое сравнение символов в строке. Хотя для этого есть стандартная библиотечная функция, вы можете использовать operator <значений std :: string в вашем классе:

friend bool operator<(AString const& a, AString const& b)
{
return a.value < b.value;
}

РЕДАКТИРОВАТЬ: Вы также можете удалить свои операторы преобразования или, по крайней мере, сделать их явными, что предотвращает неожиданные и нежелательные неявные преобразования. Конструкторы, принимающие один параметр (кроме конструкторов копирования или перемещения), также должны быть объявлены явными.

ответил(а) 2021-01-25T22:07:41+03:00 4 месяца, 2 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема