Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.61/56: Рейтинг темы: голосов - 56, средняя оценка - 4.61
0 / 0 / 0
Регистрация: 27.01.2015
Сообщений: 4

Контейнеры, способные хранить данные произвольных (различных) типов

29.01.2015, 22:23. Показов 10547. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый лень. Существуют ли контейнеры (стандартные, не стандартные - не важно), которые способны хранить данные разных типов, то есть каждый элемент контейнера имеет свой тип, и я мог обращаться к ним по их номеру (как в массиве или векторе). Конкретно, нужно, что бы хранились ссылки на функции разных типов (с разными параметрами).
Заранее спасибо за помощь.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.01.2015, 22:23
Ответы с готовыми решениями:

Как stl контейнеры работают с объектами различных типов данных?
Интересует определяют ли STL контейнеры (в частности vector) какой тип данных они хранят, для соответсвтующей работе с ними в памяти? Если...

Как прочитать из файла данные различных типов?
Имеется файл такого вида: Надо написать программу, которая прочтёт эти данные из файла и запишет их в нужные переменные. ...

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

13
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
29.01.2015, 22:34
Мысли вслух:
возможно контейнер элементов pair<type, void*>
C++
1
std::vector<std::pair<ElementType, void*>>
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
29.01.2015, 22:36
Цитата Сообщение от GAmesDmin Посмотреть сообщение
Существуют ли контейнеры (стандартные, не стандартные - не важно), которые способны хранить данные разных типов
http://rextester.com/RNA31255

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//Title of this code
//Compiler Version 18.00.21005.1 for x86
 
#include <iostream>
#include <vector>
#include <boost/any.hpp> //<--- позиционируется, как "безопасный контейнер любых типов"
                                          // хотят тот ещё тормоз
int main()
{
    std::cout << "Hello, world!\n";
    
    typedef ::std::vector<::boost::any>
        container;
    
    
    container example;
    
    example.emplace_back(10);
    example.emplace_back(true);
    example.emplace_back("hello");
    
    for(const auto& i: example)
        ::std::cout<<"type of element: '"<<i.type().name()<<"'\n";
}
Цитата Сообщение от GAmesDmin Посмотреть сообщение
Конкретно, нужно, что бы хранились ссылки на функции разных типов (с разными параметрами).
Простой, но неэффективный путь - использовать std::function параметризованный boost::any.

Если ваша задача не критична к скорости, то в общем то нормальный вариант.
Хоть и слегка тормозной.
----------------------------------------------------------------------

Под вашу задачу просится механизм "динамический делегат".

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

Его использование выглядит так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
...
 
void foo(int){}
 
struct bar
{
   void work(){}
};
 
...
 
int main()
{
    typedef std::vector<connector>
        connectors;
 
    connectors con;
 
    con.emplace_back(&foo); //<--- нацеливание на свободную функцию
 
    bar obj;
 
    con.emplace_back(obj, &bar::work); //<--- нацеливание на метод класса
 
    con[0](10); // <--- эквивалент foo(10);
    con[1]();    // <--- эквивалент obj.work();
}
В принципе, изготовление не очень сложное.
Хотя конечно есть свои нюансы.

Но если вы владеете шаблонами хотя бы на базовом уровне - вполне можно осилить.
Если хотите - могу показать вам рецепт изготовления мопеда.
0
0 / 0 / 0
Регистрация: 27.01.2015
Сообщений: 4
30.01.2015, 14:52  [ТС]
Да, хотелось бы посмотреть на горный велосипед, так как первый вариант не подходит. Как раз скорость - это очень важно для моей задачи!
0
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
30.01.2015, 18:06
hoggy, я бы тоже хотел увидеть велик.
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
30.01.2015, 18:26
Как вариант.
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
30.01.2015, 19:21
Цитата Сообщение от DiffEreD Посмотреть сообщение
я бы тоже хотел увидеть велик.
ааа, хорошо не вопрос.
Только мой посыл был не за сам велик в готовом варианте.
Потому что это много буковок. Шаблоно-буковок.

Мой посыл был за рецепт изготовление.

То есть воспроизвести механизм шаг за шагом, заодно обмусолив все его детали.

Тогда будет понятно, как это на самом деле все изготавливается.

А если просто тупо исходник открыть - ну можно... только толку от этого наверное не очень много?
Там же без 100 грамм не понять ничего ))

На самом деле он состоит из нескольких частей,
каждая из которых - самостоятельный инструментальный механизм.

Что бы его понять (построить), нужно воспроизвести все эти части.
0
30 / 47 / 19
Регистрация: 23.10.2014
Сообщений: 1,001
30.01.2015, 21:09
моя кривая ламерская реализации нетипизированного стека, делал сто лет назад, возможны недоделки...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class Stack
{
private:
    struct Node
    {
        Node* prev = nullptr;
        unsigned char* data = nullptr;
    } *last = nullptr;
 
public:
    Stack() {}
 
    ~Stack()
    {
        while (last) pop();
    }
 
    template<typename T>
    void push(const T &data)
    {
        static_assert(!std::is_pointer<T>::value, "Type should not be a pointer");
        Node* tmp = new Node;
        tmp->prev = last;
        T* ptr = new T;
        *ptr = data;
        tmp->data = (unsigned char*) ptr;
        last = tmp;
    }
 
    void pop()
    {
        if (!last) return;
        delete last->data;
        Node* tmp = last->prev;
        delete last;
        last = tmp;
    }
 
    template<typename T>
    const T& peek() const
    {
        if (!last) throw("Stack is empty");
        return *((T*) last->data);
    }
};
0
Неэпический
 Аватар для Croessmah
18147 / 10731 / 2066
Регистрация: 27.09.2012
Сообщений: 27,030
Записей в блоге: 1
30.01.2015, 21:17
Цитата Сообщение от Dark Byte Посмотреть сообщение
C++
1
delete last->data;
а деструктор кто вызывать будет?
0
30 / 47 / 19
Регистрация: 23.10.2014
Сообщений: 1,001
30.01.2015, 21:57
Цитата Сообщение от Croessmah Посмотреть сообщение
а деструктор кто вызывать будет?
delete сам вызывает деструктор
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
30.01.2015, 21:58
Цитата Сообщение от Dark Byte Посмотреть сообщение
моя кривая ламерская реализации нетипизированного стека, делал сто лет назад, возможны недоделки...
судя по наличию с++11 насчет ста лет - это вы конечно погорячились.
0
Неэпический
 Аватар для Croessmah
18147 / 10731 / 2066
Регистрация: 27.09.2012
Сообщений: 27,030
Записей в блоге: 1
30.01.2015, 22:02
Цитата Сообщение от Dark Byte Посмотреть сообщение
delete сам вызывает деструктор
откуда он знает какой деструктор вызывать? Указатель unsigned char, информация о типе потеряна

Добавлено через 56 секунд
Цитата Сообщение от hoggy Посмотреть сообщение
судя по наличию с++11 насчет ста лет - это вы конечно погорячились.
красава
0
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
31.01.2015, 17:43
Вот мои старания:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include <functional>
 
template<typename F>
class holder;
 
class connector
{
    std::shared_ptr<connector> mPtr;
public:
    connector() = default;
    virtual ~connector() = default;
 
    template<typename F, typename... Args>
    explicit connector(const F& f, Args&&... args) : mPtr(new holder<F>(f, std::forward<Args>(args)...)) {}
 
    virtual void call() const { mPtr->call(); }
 
    void operator ()() const {call();}
};
 
template<typename F>
class holder : public connector
{
    std::function<void()> func;
public:
    template <typename... Args>
    holder(const F& f, Args&&... args) : func(std::bind(f, std::forward<Args>(args)...)) {}
 
    virtual void call() const override { func(); }
};
 
////////////////////////////////////////////////////////////////////////////////
 
void foo() {std::cout << "void foo()\n";}
 
void foo1(const std::string& s, int val)
{
   std::cout << s << " " << val << "\n";
}
 
int foo2(const std::string& s, int val, double d)
{
   std::cout << s << " " << val << " " << d << "\n";
   return val;
}
 
struct Foo {
   void operator ()(int val) const {std::cout << "Foo::operator(int)\n";}
};
 
int main()
{
   std::vector<connector> con;
   con.emplace_back(foo);
   con.emplace_back(foo1, "Hello", 42);
   con.emplace_back(foo2, "world", 84, 12.2);
   con.emplace_back(std::bind(Foo(), 42));
 
   for (auto &f : con) f();
}
Только параметры надо передавать сразу на месте и есть проблема вывода возвращаемого типа (по умолчанию всегда void).
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
31.01.2015, 18:24
Цитата Сообщение от DiffEreD Посмотреть сообщение
Только параметры надо передавать сразу на месте и есть проблема вывода возвращаемого типа (по умолчанию всегда void).
Это совсем не то)

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

1. Не должно быть ограничений на возвращаемое значение.
2. Не должно быть обязательного требования заранее биндить аргументы.

----------------------------------------------------------------------

А вот если заранее известен тип возвращаемого значения,
то задача легко решается в статике при помощи обычных биндов и std::function
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
31.01.2015, 18:24
Помогаю со студенческими работами здесь

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

Возможно ли хранить данные сkeditor в txt фаиле или это не правильно там их хранить?
В пред идущих темах я начал разбираясь с установкой этого чудесного редактора. У меня вопрос возможно ли хранить данные сkeditor в txt...

Как хранить набор произвольных свойств для товара
Задача такая есть произвольный набор свойств у товара. Например Место на полке (в центре, сверху, снизу и т.д) Цвет (белый, черный,...

Пагинация для произвольных типов записей
Всем привет. Использую произвольный тип записей и вывожу их на странице (home.php) вот так: &lt;?php query_posts() ?&gt; &lt;?php...

Добавить в список указатели на обьекты произвольных типов
Доброго времени суток, плиз помогите кто чем может ,имеется класс class TGarbageCollector { public: template...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru