2009-09-30 2 views
4

У меня есть Предполагаемый типа я буду называть NamedNestedMapУплотненный станда :: Карты

std::map<std::string, std::map<std::string, NamedNestedMap> > 

В этом случае каждое второе (значение) из пары является тот же вид или типа в качестве родительского объекта. Я не могу понять, как объявить об этом. Это позволит рекурсивному алгоритму спуститься через «дерево» карт.

Тип значения такой же, как тип родителя, который в точке, где мне нужно ссылаться, не полностью объявлен.

Как объявить что-то вложен как это ...

я не могу даже ЬурейеЕ первый, так что я могу включить его второй, потому что это неполный

Рекурсия будет искать что-то в карта, когда она находит это, рекурсивно оценивает значение этого объекта. Часть алгоритма выглядит довольно прямолинейно, часть декларации - вот здесь. Я не пытаюсь перебрать карту карт, просто используйте map.find, recurse и снова используйте map.find.

+0

Я не понимаю вашего вопроса. –

+1

Я думаю, что ваш компилятор может взорваться, если продолжить эту линию рассуждений. Каким будет тип итератора этого класса? –

ответ

8

Вы должны использовать указатели (естественно, так как в противном случае рекурсия никогда не прекращается - вы всегда будете нуждаться в еще одну пустую карту):

struct NestedMap; 
struct NestedMap : std::map<std::string, NestedMap*> {}; 

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

+3

Из того, что я слышал, наследование класса STL - это плохо. – strager

+5

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

2

Вы не можете объявить рекурсивную структуру.

Лучшее, что вы могли бы сделать, это иметь карту карты указателя.

1

Проблема в том, что ваше определение типа для NamedNestedMap не имеет терминации в своей рекурсивной структуре. Расширение шаблона для NamedNestedMap будет бесконечным и, следовательно, его код в коде невозможен.

5

Создайте структуру, представляющую узел.

struct Node { 
    std::map<std::string, Node *> children; 
}; 

Вы можете, конечно, сделать его классом и скрыть данные и т. Д.

1

Похоже, что вы хотите сделать что-то вроде этого:

class Node { 
    ... 

    std::map<std::string, Node*> children; 
} 

Здесь каждый Node есть карта «дети» в карте, и это дети могут иметь детей, и так далее.

0

Вы не можете сделать это так, как вы его представляете, и вы, вероятно, этого не хотите. Причина в том, что пары на карте сохраняются по значению. Вы хотите, чтобы ваша таблица имен и значений была скопирована в другой контейнер? Я бы пошел на обертку вдоль линий @strager и Pavel, предложив , используя опциональные умные указатели.

4

Я предполагаю, что вы хотите иметь вложенную карту глубины п:

template<class key_type, class val_type, int nest_depth> 
struct nest 
{ 
typedef std::map<key_type, typename nest<key_type, val_type, 
       nest_depth-1>::map_type> map_type; 
}; 

template<class key_type, class val_type> 
struct nest<key_type, val_type, 0> 
{ 
    typedef std::map<key_type, val_type> map_type; 
}; 

использовать его как это:

nest<std::string, std::string, 2> nested_map; 
+1

Если я правильно понимаю его вопрос, он хочет иметь действительно рекурсивную структуру данных (по существу, дерево), поэтому 'n' будет« + INF », так сказать. –

+0

Хорошо, я об этом не думал. Я думал о глубине, когда он пытался объявить это в первую очередь. –

0

Это, кажется, собрать для меня:

#include <map> 
#include <string> 

struct RecMap 
{ 
    std::map<std::string, RecMap> m; 
}; 

int main() 
{ 
    RecMap rec; 
    rec.m["first"] = RecMap(); 
    rec.m["first"].m["second"] = RecMap(); 
} 

Не 100% уверены, что это законно (например, у вас есть класс X, который содержит vector<X> в качестве участника?). Рекурсия здесь не бесконечна, так как в конечном итоге вы столкнетесь с RecMap, содержащим пустую карту.

Редактировать: this article Обсудить ситуацию. Вывод: неопределенный. Сожалею.

0

Я думаю, что создание рекурсивной структуры может вызвать проблемы. Просто используйте обычные карты, как это:

#include <map> 
#include <string> 

using namespace std; 

int main() { 
    map<string, map<string, string> > nest; 
    nest["first"]["second"] = "Hello nest!"; 
    printf("%s\n", nest["first"]["second"].c_str()); 
    return 0; 
} 

А вот исполнение:

$ g++ ./nest.cpp -o nest.out -ansi -pedantic -std=c++98 
$ ./nest.out 
Hello nest! 
$ 
Смежные вопросы