Передача карт с различными типами значений в функцию в C ++ - PullRequest
1 голос
/ 21 марта 2012

Мне нужно добавить новую функциональность в старый, плохо написанный код. Существует 50 различных списков, которые необходимо отображать и обрабатывать на экранах, и текущий код для них - все вырезано и вставлено с небольшими изменениями двух разных типов: один список в базе данных DAO, а другой на карте.

Я написал класс Search, который обеспечивает функциональность, и вспомогательный класс для каждого из типов списков, чтобы обеспечить основные функции, необходимые для Search. Вспомогательный класс map требует только доступа к ключу tstring, ему не нужны разные значения объекта. Но я не могу заставить это скомпилировать.

Поскольку различные разные объекты не имеют отношения, я определил класс SearchValue, который в основном пустой, и добавил его в .h как суперкласс для всех классов различных объектов.

В качестве примера приведем одно из определений карты:

typedef map<tstring, MyPatListEntry *, tstringcomp> patlist;

MyPatListEntry определено:

class MyPatListEntry : public SearchValue {

и у меня есть функция, определенная как:

ListHelper(map<tstring, SearchValue *> *map, CString fieldName) 

Компилятор (VC ++) выдает ошибку, что ни одно из определений для ListHelper () не обрабатывает все аргументы. Если я заменю SearchValue на MyPatListEntry в определении, компиляция будет работать, поэтому основной формат будет правильным.

Я осмотрел сайт и обнаружил, что люди предлагают такие вещи с помощью шаблонов функций, и я полагаю, что это сработает, но мне любопытно, есть ли причины, по которым этот способ не работает. 1018 *

Спасибо за любые мысли.

Ответы [ 2 ]

3 голосов
/ 21 марта 2012

То, что вы запрашиваете, называется ковариантными параметрами универсального типа в мире C # (невозможно в C ++), и даже там это не будет работать в вашей ситуации.Причина на самом деле довольно проста.

Представьте себе следующий код:

class B {};
class D1 : public B {};
class D2 : public B {};

map<string, D1 *> myMap;
D2 someObject;

void myFunc(map<string, B *> & someMap)
{
    someMap["foo"] = &someObject;
}

Вы не можете вызывать myFunc с myMap в качестве параметра из-за этой проблемы.Вам будет разрешено присвоить someObject типа D2 на карте, которая должна содержать D1.

0 голосов
/ 21 марта 2012

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

template <class AnySearchValue> ListHelper(map<tstring, AnySearchValue *> *map, CString fieldName) 

Трудно сказать, работоспособно ли это, не видя больше реализации. (ой, извините, пропустил в своем OP, где вы сказали, что рассмотрели это)

...