Создание класса шаблона, ассоциативного массива

При компиляции возникают проблемы следующего характера.

1). В конструкторе IContainer компилятор пишет waring: преобразование const double в int возможна потеря данных, а потом и вовсе error: не найден оператор принимающий правый операнд хотя std::map вроде как позволяет так обращаться к элементам

    IContainer<ElemType, IndexType>::IContainer(const ElemType & elem, const IndexType & index)
    {
            arr[index]=elem;
    }

2). В ф-ии GetElem несоответствие типов со знаком и без. строчка с return возвр. адреса локальной или временной переменной, тоже не ясно.

    const ElemType& IContainer<ElemType, IndexType>::GetElem(const IndexType & index)
    {
        if(index>arr.size())
            std::cout<<"exception \n";
            throw ElemNotFound<IndexType> /*err */(index);
        return arr[index];
    }

3). В PutElem преобразование const double в int возможна потеря

    void IContainer<ElemType, IndexType>::PutElem(const IndexType& index, const ElemType& elem)
    {
        arr.at(index)=elem; //??
    }

4). Последнее, самое сложное не могут состыковаться блоки throw и catch я после слова throw создаю объект и хочу передать его в блок catch по ссылке, но он туда не лезет ни в какую, пробовал как мне кажется по всякому уже.

    throw ElemNotFound<IndexType> /*err */(index);
    ...
    try
        {
        std::cout<<blablabla.GetElem(7)<<"  "<<obj.GetElem(1);
        }
        catch(/*ElemNotFound<IndexType>::*/ElemNotFound & bg/*...*/)
        {
            std::cout<<"exeption";//bg.mesg();
        }

Весь код:

    #include "stdafx.h"
    #include <string>
    #include <iostream>
    #include <map>

    template<class IndexType>
    class ElemNotFound
    {
    private:
    IndexType value;
    public:
    ElemNotFound(IndexType index):value(index){}
    void mesg();
    };
    template<class IndexType>
    void ElemNotFound<IndexType>::mesg()
    {
    std::cout<<"Element #"<<value<<" not found\n";
    }


    template <class ElemType, class IndexType> class IContainer
    {
    private:
    std::map<ElemType, IndexType> arr;
    public:
    IContainer() {};
    IContainer(const ElemType & elem, const IndexType & index);
    virtual const ElemType& GetElem( const IndexType& index ) /*const throw ( ElemNotFound ) = 0*/;
    virtual void PutElem( const IndexType& index, const ElemType& elem ) /*throw () = 0*/; //первый это номер элемента в массиве, второй сам элемент
    };
    template<class ElemType, class IndexType>
    IContainer<ElemType, IndexType>::IContainer(const ElemType & elem, const IndexType & index)
    {
    arr[index]=elem;
    }
    template<class ElemType, class IndexType>
    void IContainer<ElemType, IndexType>::PutElem(const IndexType& index, const ElemType& elem)
    {
    arr.at(index)=elem; //??
    }
    template<class ElemType, class IndexType>
    const ElemType& IContainer<ElemType, IndexType>::GetElem(const IndexType & index)
    {
    if(index>arr.size())
    std::cout<<"exception \n";
    throw ElemNotFound<IndexType> /*err */(index);
    return arr[index];
    }

    int main()
    {
    IContainer<double, int> obj (5, 7);
    IContainer<std::string, int> blablabla("golden joe", 6);
    blablabla.PutElem(4, "duck");
    /*IContainer<double, std::string> c;
    c.PutElem("pi", 3.14);
    c.PutElem("e", 2.71);
    std::cout << c.GetElem("pi")<<"\n";*/
    try
    {
    std::cout<<blablabla.GetElem(7)<<" "<<obj.GetElem(1);
    }
    catch(/*ElemNotFound<IndexType>::*/ElemNotFound & bg/*...*/)
    {
    std::cout<<"exeption";//bg.mesg();
    }
    return 0; 
    }

Народ хочет разобраться что к чему, дело для нас новое, не освоенное! С СТЛ и Exception-ами сталкиваюсь впервые, строго не судите!!

Сейчас код немного видоизменился:

#include "stdafx.h"
#include <string>
#include <iostream>
#include <map>

template<class IndexType>
class ElemNotFound
{
private:
    IndexType value;
public:
    ElemNotFound(IndexType index):value(index){}
    void mesg();
};

template<class IndexType>
void ElemNotFound<IndexType>::mesg()
{
    std::cout<<"Element #"<<value<<" not found\n";
}


template <class IndexType, class ElemType> class IContainer
{
private:
    std::map<IndexType, ElemType> arr;
public:
    IContainer() {};
    IContainer(const IndexType & index, const ElemType & elem);
   virtual const ElemType/*&*/ GetElem( const IndexType& index) /*const throw ( ElemNotFound ) = 0*/;
   virtual void PutElem( const IndexType& index, const ElemType& elem ) /*throw () = 0*/;
};

template<class IndexType, class ElemType>
IContainer<IndexType, ElemType>::IContainer(const IndexType & index, const ElemType & elem)
{
        arr[index]=elem;
}

template<class IndexType, class ElemType>
void IContainer<IndexType, ElemType>::PutElem(const IndexType& index, const ElemType& elem)
{
    arr.at(index)=elem;
}

template<class IndexType, class ElemType>
const ElemType/*&*/ IContainer<IndexType, ElemType>::GetElem(const IndexType & index)
{
    arr.find(index);
    //if(index>arr.size())
        //std::cout<<"exception \n";
        //throw ElemNotFound<IndexType> /*err */(index);
    return arr[index];
//return 0;
}

int main()
{
    IContainer<double, int> obj (5, 7);
    IContainer<std::string, int> blablabla("golden joe", 6);
    blablabla.PutElem("golden joe", 4);
    /*IContainer<std::string, double> c;
   c.PutElem("pi", 3.14);
   c.PutElem("e", 2.71);
   std::cout << c.GetElem("pi")<<"\n";*/
    //try
    //{
    //std::cout<<blablabla.GetElem("golden joe")<<"  "<<obj.GetElem(1);
    //}
    //catch(/*ElemNotFound<IndexType>::ElemNotFound & bg*/)
    //{
    //  std::cout<<"exeption";//bg.mesg();
    //}
    return 0;
}

Не могу наладить эксепшн по человечьи, наверно я не понимаю как обращаться к созданному объекту. И функции в GetElem я написал find, думаю что с ним делать, и еще возник вопрос в PutElem если он обращается по неправильному индексу, надо по идее тоже эксепшен, но в задании его нет:

Необходимо разработать класс контейнера, реализующий приведенный ниже интерфейс. При разработке приветствуется использование STL.

class ElemNotFound {};
template < class ElemType, class IndexType > class IContainer
{
public:
   virtual const ElemType& GetElem( const IndexType& index ) const throw ( ElemNotFound ) = 0;
   virtual void PutElem( const IndexType& index, const ElemType& elem ) throw () = 0;
};

Если в точности следовать интерфейсу, указанному в задании, то решение может выглядеть примерно так:

#include <iostream>
#include <map>

using namespace std;

class ElemNotFound {};

template < class ElemType, class IndexType >
class IContainer {
private:
    map< IndexType, ElemType > data;
public:
    virtual const ElemType& GetElem(const IndexType& index) const throw (ElemNotFound);
    virtual void PutElem(const IndexType& index, const ElemType& elem) throw ();
};


template < class ElemType, class IndexType >
const ElemType& IContainer< ElemType, IndexType >::GetElem(const IndexType& index) const throw (ElemNotFound) {
    const map< IndexType, ElemType >::const_iterator it = data.find(index);
    if (it == data.end())
        throw ElemNotFound();
    return it->second;
}

template < class ElemType, class IndexType >
void IContainer< ElemType, IndexType >::PutElem(const IndexType& index, const ElemType& elem) throw () {
    data[index] = elem;
}


int main() {
    IContainer<const char *, int> cont;
    try {
        cont.PutElem(5, "square is 25");
        cont.PutElem(6, "square is 36");
        cont.PutElem(8, "square is 64");
        cont.PutElem(8, "square is approximately 64 ;)");

        cout << "key = 5 elem = " << cont.GetElem(5) << endl;
        cout << "key = 6 elem = " << cont.GetElem(6) << endl;
        cout << "key = 8 elem = " << cont.GetElem(8) << endl;
        cout << "key = 7 elem = " << cont.GetElem(7) << endl;
        cout << "after exception" << endl;
    }
    catch (ElemNotFound) {
        cerr << "Element not found." << endl;
    }
    return 0;
}

Здесь при вставке элемента, если ключ дублируется, просто тихо происходит замена значения, связанного с ключом, на новое. Что есть не очень хорошо, но удовлетворяет спецификации из задания.

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.

Ответить

Вы можете использовать разметку markdown для оформления комментариев и постов. Используйте функцию предпросмотра для проверки корректности разметки.

Пожалуйста, оформляйте исходный код в соответствии с правилами разметки. Для того, чтобы вставить код в комментарий, скопируйте его в текстовое поле ниже, после чего выделите то, что скопировали и нажмите кнопку «код» в панели инструментов. Иначе ваш код может принять нечитаемый вид.

Либо производите оформление кода вручную, следующим образом:

``` #include <iostream> using namespace std; int main() { // ... } ```

Предпросмотр сообщения

Ваше сообщение пусто.