C++ template и связные списки (Как засунуть template классы в связный список)

Модератор: Модераторы разделов

Аватара пользователя
sarutobi
Сообщения: 676
Статус: Добрость и скромнота
ОС: Debian 5, FreeBSD 6.2/8.0

C++ template и связные списки

Сообщение sarutobi »

Доброго времени суток!
Возникла задачка, как решить никак не соображу. Есть примерно такой шаблон:

Код: Выделить всё

template typename<V> class holder{
private:
V* value;
public:
V* get();
void put (V* newValue);
}

Необходимо сделать связный список из элементов, производных от шаблона. Общее число элементов (пока) 6, дальше неизвестно.
Вроде бы получилось вот такое решение:

Код: Выделить всё

template typename <L, V> class holder{
private:
L* linker;
V* value;
public:
V* get();
void put(V* value);
L* getLinker();
}
class Linker{
private:
Linker* next;
public:
Linker* next();
}

Но как получить доступ к holder объекту после my->getLinker()->next(); непонятно. Или подскажите другой способ организации списка.
Fire and water, earth and sky - mistery surrounds us, legends never die!
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: C++ template и связные списки

Сообщение Zeus »

В STL (std::list) всё уже давно реализовано и "засунуто".
Спасибо сказали:
Аватара пользователя
sarutobi
Сообщения: 676
Статус: Добрость и скромнота
ОС: Debian 5, FreeBSD 6.2/8.0

Re: C++ template и связные списки

Сообщение sarutobi »

Zeus писал(а):
11.07.2008 09:49
В STL (std::list) всё уже давно реализовано и "засунуто".

template typename<T> list - описание списка из STL. Мне нужно template typename<template> list. Разницу чуствуете?
Fire and water, earth and sky - mistery surrounds us, legends never die!
Спасибо сказали:
Аватара пользователя
Clear_Mind
Сообщения: 241
Статус: Изредко заглядывающий
ОС: openSuSE 11.1

Re: C++ template и связные списки

Сообщение Clear_Mind »

Код: Выделить всё

template < class V> class Holder {
private:
    next* Holder;
    prev* Holder; //если нужна обратная связь
    V* value;
public:
    V* get();
    void put(V* value);
    Holder* getNext();
    Holder* getPrev();
};

Вот такой вариант пойдет?

Мне нужно template typename<template> list

Шаблоны "разрешаются" во время компиляции, и после нее не могут быть изменены, по этому можеть возникнуть куча проблем у компилятора при таком объявлении. Я бы попробовал посмотреть в сторону полиморфизма и виртуальных функций.
Bombers launch with no recall + Minutes warning of the missile fall
Take a look at your last sky + Guessing you won't have the time to cry
--- Iron Maiden (Brouther Than A Thousand Suns, 2006)
Спасибо сказали:
Аватара пользователя
sarutobi
Сообщения: 676
Статус: Добрость и скромнота
ОС: Debian 5, FreeBSD 6.2/8.0

Re: C++ template и связные списки

Сообщение sarutobi »

спасибо, это классический список. он не подходит по причине - мне нужно хранить 6 типов V* в одном списке. Про шаблоны знаю, но задача стоит именно такая
Сделать список который будет содержать произвольные предопределенные данные. Сижу, курю всякую литературу, пока результата нет :(
Fire and water, earth and sky - mistery surrounds us, legends never die!
Спасибо сказали:
Аватара пользователя
Clear_Mind
Сообщения: 241
Статус: Изредко заглядывающий
ОС: openSuSE 11.1

Re: C++ template и связные списки

Сообщение Clear_Mind »

Код: Выделить всё

struct Values {
    some_type1 first;
    some_type2 second;
    //...
    Values(some_type1 f, /* ... */): first(f), /* ... */ {}
};

Т.к. все равно придется задавать конкретные типы всем полям структуры (все 6 различных типов должны быть строго определены на момент компиляции), имеет смысл в отдельном .h файле разместить вышеприведенную структуру и использовать как Holder<Values>. Values безусловно может быть тоже шаблоном.
Bombers launch with no recall + Minutes warning of the missile fall
Take a look at your last sky + Guessing you won't have the time to cry
--- Iron Maiden (Brouther Than A Thousand Suns, 2006)
Спасибо сказали:
Serik
Сообщения: 149
ОС: SuSE Linux

Re: C++ template и связные списки

Сообщение Serik »

sarutobi писал(а):
11.07.2008 11:36
спасибо, это классический список. он не подходит по причине - мне нужно хранить 6 типов V* в одном списке. Про шаблоны знаю, но задача стоит именно такая
Сделать список который будет содержать произвольные предопределенные данные. Сижу, курю всякую литературу, пока результата нет :(

Не понял в чем проблема,
структура известна в момент компиляции ? тогда std::list
или структура определяется в run-time ? т.е. нужен класс типа VCL::TDataSet ? Я для этого написал свой класс.
Спасибо сказали:
Аватара пользователя
innkeeper
Сообщения: 110

Re: C++ template и связные списки

Сообщение innkeeper »

А у вас в одном списке элементы будут одного и того же типа?
Спасибо сказали:
Аватара пользователя
sarutobi
Сообщения: 676
Статус: Добрость и скромнота
ОС: Debian 5, FreeBSD 6.2/8.0

Re: C++ template и связные списки

Сообщение sarutobi »

innkeeper писал(а):
11.07.2008 12:09
А у вас в одном списке элементы будут одного и того же типа?

в том то и дело что нет. Единственное - они будут производными от шаблона.
Serik - структура известна на момент компиляции. проблема в том что она не одна. Что такое VCL::DataSet и можно ли посмотреть на Ваш класс?
Структура с всеми полями известного типа не подходит-класс библиотечный
Fire and water, earth and sky - mistery surrounds us, legends never die!
Спасибо сказали:
nestoklon
Сообщения: 42
ОС: M$, linux

Re: C++ template и связные списки

Сообщение nestoklon »

sarutobi писал(а):
11.07.2008 11:36
спасибо, это классический список. он не подходит по причине - мне нужно хранить 6 типов V* в одном списке. Про шаблоны знаю, но задача стоит именно такая
Сделать список который будет содержать произвольные предопределенные данные. Сижу, курю всякую литературу, пока результата нет :(

Не до конца понимаю. Или это делается классическим списком (хоть связным, хоть массивом) указателей на класс, от которого наследуется всё то что предполагается в этом массиве хранить или вы хотите странного.

upd Или это делается с помощью указателя на void
Спасибо сказали:
Аватара пользователя
sarutobi
Сообщения: 676
Статус: Добрость и скромнота
ОС: Debian 5, FreeBSD 6.2/8.0

Re: C++ template и связные списки

Сообщение sarutobi »

nestoklon писал(а):
11.07.2008 13:11
Не до конца понимаю. Или это делается классическим списком (хоть связным, хоть массивом) указателей на класс, от которого наследуется всё то что предполагается в этом массиве хранить или вы хотите странного.
upd Или это делается с помощью указателя на void

Возможно я хочу странного. Попытаюсь еще раз подробно описать ситуацию. В приведенном шаблоне класса Holder интерес представлят только сигнатура V* get(), позволяющая получить типизированное значение переменной. Типов V пока 6, возможно их будет больше => сейчас есть 6 классов с разным типом возвращаемого значения. Это меня полностью устраивает. Мне нужен список из элементов, определенных шаблоном, причем в списке могут быть как одинаковые, так и разные элементы. Void* как вариант хранения - тогда не нужны все эти пляски с шаблонами, достаточно void* get(),, но я не могу в рантайме кастовать void* к требуемому типу - он может быть любым + не хочется делать все через <dynamic_cast>
Fire and water, earth and sky - mistery surrounds us, legends never die!
Спасибо сказали:
nestoklon
Сообщения: 42
ОС: M$, linux

Re: C++ template и связные списки

Сообщение nestoklon »

sarutobi писал(а):
11.07.2008 13:23
Возможно я хочу странного. Попытаюсь еще раз подробно описать ситуацию. В приведенном шаблоне класса Holder интерес представлят только сигнатура V* get(), позволяющая получить типизированное значение переменной. Типов V пока 6, возможно их будет больше => сейчас есть 6 классов с разным типом возвращаемого значения. Это меня полностью устраивает. Мне нужен список из элементов, определенных шаблоном, причем в списке могут быть как одинаковые, так и разные элементы. Void* как вариант хранения - тогда не нужны все эти пляски с шаблонами, достаточно void* get(),, но я не могу в рантайме кастовать void* к требуемому типу - он может быть любым + не хочется делать все через <dynamic_cast>

Так. Стандартно это делается следующим образом: Мы наследуем все 6 классов от Holder и делаем обычный нешаблонный список указателей на Holder. После этого вызываем виртуальную функцию из класса Holder, которая перепределена для каждого класса так, чтобы сделать нечто, зависящее от типа класса.
Вы хотите чтобы эти классы возвращали разные типы. Это невозможно, поскольку вы не сможете потом этими результатами воспользоваться. Они же неизвестного типа! В стандарте c++ anytype нет.
tip: попробуйте написать пример использования вашего хитрого списка и поймёте, о чём я.
Спасибо сказали:
Аватара пользователя
innkeeper
Сообщения: 110

Re: C++ template и связные списки

Сообщение innkeeper »

Попробуйте что-то вроде этого. И используйте список из стандартной библиотеки.

Код: Выделить всё

class Holder
{
    void* _p;

    public:
        Holder();
        template<class V> void set(V& val)
        {
            _p = (void*) new V;
            *_p = val;
        }

        template<class V> void get(V& val)
        {
            val = *_p;
        }
};


Либо посмотрите в Boost какой-нибудь tuple. Либо поищите в инете как реализовывать tuple и напишите свой.
Спасибо сказали:
nestoklon
Сообщения: 42
ОС: M$, linux

Re: C++ template и связные списки

Сообщение nestoklon »

Да, и мне кажется, вы зря пытаетесь смешать объекты с шаблонами.
Не для гуру лучше бы сначала написать обычные классы, а потом делать их шаблонными.
Шаблоны разрешаются на этапе компиляции. Шаблонный класс с разным параметром шаблона -- это два разных класса. Мне кажется, вы это не учитываете.
Спасибо сказали:
Аватара пользователя
sarutobi
Сообщения: 676
Статус: Добрость и скромнота
ОС: Debian 5, FreeBSD 6.2/8.0

Re: C++ template и связные списки

Сообщение sarutobi »

nestoklon писал(а):
11.07.2008 13:45
Да, и мне кажется, вы зря пытаетесь смешать объекты с шаблонами.
Не для гуру лучше бы сначала написать обычные классы, а потом делать их шаблонными.
Шаблоны разрешаются на этапе компиляции. Шаблонный класс с разным параметром шаблона -- это два разных класса. Мне кажется, вы это не учитываете.

Я это прекрасно знаю и учитываю. Осталось только написать холдер, который умеет держать шаблонные параметры.
Fire and water, earth and sky - mistery surrounds us, legends never die!
Спасибо сказали:
Аватара пользователя
innkeeper
Сообщения: 110

Re: C++ template и связные списки

Сообщение innkeeper »

Да берите tuple из Boost и не надо будет даже holder писать.
Спасибо сказали:
nestoklon
Сообщения: 42
ОС: M$, linux

Re: C++ template и связные списки

Сообщение nestoklon »

innkeeper писал(а):
11.07.2008 13:56
Да берите tuple из Boost и не надо будет даже holder писать.

+1
Спасибо сказали:
Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8259
Статус: Маньяк
ОС: Arch, Fedora, Ubuntu

Re: C++ template и связные списки

Сообщение serzh-z »

sarutobi
Я бы сделал подобный костыль:

Код: Выделить всё

#include <algorithm>
#include <iostream>
#include <list>
#include <string>

class basic_holder {
    public:
        virtual void polymorph_() {};
};

template<class T> class holder : public basic_holder {
    private:
        T value_;

    public:
        T get() {
            return value_;
        }

        void put(T value) {
            value_ = value;
        }
};

int main()
{
    std::list<basic_holder *> l;
    holder<std::string> *h1 = new holder<std::string>;
    holder<int> *h2 = new holder<int>;
    holder<char *> *h3 = new holder<char *>;

    h1->put("HELLO;]");
    h2->put(99);
    h3->put("test");

    l.insert(l.end(), h1);
    l.insert(l.end(), h2);
    l.insert(l.end(), h3);

    std::cout << dynamic_cast<holder<char *> *>(l.back())->get() << std::endl;

    return 0;
}


Но поскольку dynamic_cast не устраивает, то, видимо, увы.
Спасибо сказали:
Аватара пользователя
sarutobi
Сообщения: 676
Статус: Добрость и скромнота
ОС: Debian 5, FreeBSD 6.2/8.0

Re: C++ template и связные списки

Сообщение sarutobi »

nestoklon писал(а):
11.07.2008 13:40
Так. Стандартно это делается следующим образом: Мы наследуем все 6 классов от Holder и делаем обычный нешаблонный список указателей на Holder. После этого вызываем виртуальную функцию из класса Holder, которая перепределена для каждого класса так, чтобы сделать нечто, зависящее от типа класса.
Вы хотите чтобы эти классы возвращали разные типы. Это невозможно, поскольку вы не сможете потом этими результатами воспользоваться. Они же неизвестного типа! В стандарте c++ anytype нет.
tip: попробуйте написать пример использования вашего хитрого списка и поймёте, о чём я.

Пример использования списка

Код: Выделить всё

MyVariables holder;
IntTemplate integer("int example", 5);
StringTemplate string("string example", "lalala");
holder.add(integer);
holder.add(string);
std::string test = holder.get("string example").get();

Кроме того, я нашел варианты решения данной задачи, сейчас экспериментирую.
serzh-z - спасибо это почти то что нужно и к чему я пришел. <dynamic_cast> не хотелось бы распихивать по всему коду.
Fire and water, earth and sky - mistery surrounds us, legends never die!
Спасибо сказали:
nestoklon
Сообщения: 42
ОС: M$, linux

Re: C++ template и связные списки

Сообщение nestoklon »

sarutobi писал(а):
11.07.2008 13:53
Осталось только написать холдер, который умеет держать шаблонные параметры.

осталось понять, почему не устраивает dynamic_cast, если для корректного использования списка всё равно нужно знать, результат какого типа мы извлекаем.
Спасибо сказали:
nestoklon
Сообщения: 42
ОС: M$, linux

Re: C++ template и связные списки

Сообщение nestoklon »

sarutobi писал(а):
11.07.2008 14:07
Пример использования списка

Код: Выделить всё

MyVariables holder;
IntTemplate integer("int example", 5);
StringTemplate string("string example", "lalala");
holder.add(integer);
holder.add(string);
std::string test = holder.get("string example").get();

Кроме того, я нашел варианты решения данной задачи, сейчас экспериментирую.
serzh-z - спасибо это почти то что нужно и к чему я пришел. <dynamic_cast> не хотелось бы распихивать по всему коду.

Это не нескафе список. Это ассоциативный массив какой-то.
Поделитесь пожалуйста результатом -- очень интересно понять, что же всё-таки было нужно.
Спасибо сказали:
Аватара пользователя
Electronix
Сообщения: 53
ОС: Slackware, Suse, XP

Re: C++ template и связные списки

Сообщение Electronix »

Я правильно понимаю что нужен список классов/типов ?
Тогда нужно смотреть книгу Александреску - Современные проэктирование на С++.
We have no beginning, we have no end. We are infinite.
Спасибо сказали:
Аватара пользователя
sarutobi
Сообщения: 676
Статус: Добрость и скромнота
ОС: Debian 5, FreeBSD 6.2/8.0

Re: C++ template и связные списки

Сообщение sarutobi »

Electronix писал(а):
13.07.2008 14:52
Я правильно понимаю что нужен список классов/типов ?
Тогда нужно смотреть книгу Александреску - Современные проэктирование на С++.


Вот именно её и смотрел :) В принципе, получил то что хотел, кому интересно - результат в аттаче.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Fire and water, earth and sky - mistery surrounds us, legends never die!
Спасибо сказали: