2015-10-04 6 views
0

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

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

... 

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 

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

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++, так что могут быть и другие ошибки. Если да, не стесняйтесь указывать их.

Спасибо!

EDIT:

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 
+1

Вы не указали достаточно кода, чтобы воспроизвести проблему. Каково определение «AString»? –

+0

@NeilKirk Определение включено. Вы имели в виду декларацию? – Qub1

+0

Все это. В противном случае, как я могу определить, какой тип 'значение' и т. Д.? –

ответ

4

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

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

Правильная вещь - лексикографически сравнивать символы в строке. В то время как стандартная функция библиотеки, чтобы сделать это, вы можете использовать оператор < из станд :: строковые значения в классе:

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

EDIT: Вы также можете удалить ваши операторы преобразования, или, по крайней мере, сделать они явные, что предотвращает неожиданные и нежелательные неявные преобразования. Конструкторы, принимающие один параметр (кроме конструкторов копирования или перемещения), также должны быть объявлены явным.

+0

Спасибо за help, это работает так, как ожидалось. Если я удалю операторы преобразования, каким будет рекомендуемый способ использования моего объекта AString, например, std :: string? их явный единственный путь? – Qub1

+0

Вы можете создать AString, просто вызвав соответствующий конструктор со стандартной строкой и вернитесь к std :: string, вызвав явный оператор преобразования или специально реализованную функцию-член (как предлагает Neil Kirk выше). – user673679