Шаблонная карта C ++ содержит себя - PullRequest
3 голосов
/ 07 августа 2011

У меня есть шаблонный класс, который может иметь тип карты в качестве параметра шаблона.

template<typename map_t> class my_class
{
    map_t my_map;
};

Теперь я бы хотел, чтобы тип значения карты был равен этому классу.

my_class<std::map<std::string, my_class<...> > > problems;

Однако об этом невозможно заявить. Как мне добиться того же эффекта?

Ответы [ 7 ]

1 голос
/ 07 августа 2011

Поскольку вы хотите быть универсальным в типе контейнера, самое близкое, что я смог найти (если я хорошо понимаю ваши намерения), это:

template <template <typename, typename> class Map>
struct my_class
{
    typedef typename Map<std::string, my_class>::type map_t;
    map_t children;
};

// Since the standard doesn't allow default arguments to be
// taken into account for template template parameters, we
// have to close them.
// Write one such structure for each map type you want.
struct std_map
{ 
    template <typename Key, typename Value>
    struct rebind { typedef std::map<Key, Value> type; }
};

и используйте

my_class<std_map::rebind> problematic_tree;
1 голос
/ 07 августа 2011

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

1 голос
/ 07 августа 2011

Вы пробовали это

template<typename T> class my_class
{

    std::map< std::string , my_class> my_map;
};

Возможно, будет лучше, если вы не передадите карту в качестве параметра шаблона, а вместо этого передадите ключ карты, значение и оператор сравнения в качестве параметров шаблона

0 голосов
/ 07 августа 2011

Класс на самом деле не может содержать самого себя в качестве члена (подумайте, сколько памяти вам понадобится для его хранения), но он может содержать указатель на себя. Вы можете реализовать это, используя приведенный шаблон J-16 SDiZ или какую-нибудь приманку и переключатель:

template<typename map_t> class my_class
{
  map_t * my_map;
};

class dummy;
template<>
class my_class<dummy>
{
  my_class<dummy> * my_map;
};
0 голосов
/ 07 августа 2011

Как отмечали другие, вы не можете создать бесконечно рекурсивное определение класса, но вы, безусловно, можете вкладывать my_class конечное число раз. Вот рабочий пример:

#include <map>
#include <string>
#include <iostream>

template<typename map_t> struct my_class {
    map_t my_map;
};

my_class<std::map<std::string, my_class<std::map<std::string, int> > > > problems;

int main() {
    std::cout << problems.my_map.size();
    return 0;
}
0 голосов
/ 07 августа 2011

Похоже, вы должны быть в состоянии переадресовать объявление my_class<T> и использовать указатель на него в качестве вашего mapped_type (в C ++ value_type означает пару, включающую в себя как ключ, так и значение для карт).

0 голосов
/ 07 августа 2011

Вы не можете этого сделать.Самое близкое, что вы можете сделать, это Любопытно повторяющийся шаблон .

...