Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
Dassis
0 / 0 / 1
Регистрация: 11.09.2015
Сообщений: 83
#1

Можно ли передать в функцию либо вектор, либо список, если да, то как?

14.10.2016, 20:38. Просмотров 1045. Ответов 16
Метки нет (Все метки)

Можно ли передать в функцию либо вектор, либо список, если да, то как?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.10.2016, 20:38
Ответы с готовыми решениями:

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

При изменении каких либо данных программа либо вылетает, либо просто не изменяет данные
Добрый вечер. Только недавно начал заниматься С++. И вот возникли проблемы. При...

две прямые либо паралельны либо совпадают либо не существуют
Д даны числа a1, b1, c1, a2, b2, c2. Напечатать координаты точки пересечения...

При потсроении пишет что конструктор либо недоступен либо объявлен как explicit
/*Все обьекты содержимые в контейнерах без проблем выводятся через потоковые...

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

16
obivan
Падаван С++
419 / 239 / 82
Регистрация: 11.11.2014
Сообщений: 845
Завершенные тесты: 2
14.10.2016, 20:40 #2
Лучший ответ Сообщение было отмечено gru74ik как решение

Решение

Dassis, через ссылку или по указателю

Добавлено через 40 секунд
ну или копию передавать, вот пример ссылки

C++
1
void func(std::vector<int> &vec);
0
Dassis
0 / 0 / 1
Регистрация: 11.09.2015
Сообщений: 83
14.10.2016, 22:33  [ТС] #3
obivan, в вашем примере передается только vector, а нужно либо массив либо вектор, тоесть я могу передать в функцию один вектор и она сработает или один список и тоже все сработает
0
GbaLog-
Любитель чаепитий
3164 / 1470 / 465
Регистрация: 24.08.2014
Сообщений: 5,200
Записей в блоге: 1
Завершенные тесты: 2
14.10.2016, 22:35 #4
Dassis,
C++
1
2
3
4
5
template< typename Cont >
void func( Cont& container )
{
    // some code
}
1
Nosey
1350 / 401 / 144
Регистрация: 22.10.2014
Сообщений: 863
Завершенные тесты: 2
14.10.2016, 22:45 #5
Лучший ответ Сообщение было отмечено gru74ik как решение

Решение

Dassis,
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
#include <iostream>
#include <vector>
#include <list>
 
void func1(std::vector<int>& vec)
{
    std::cout << "void func1(std::vector<int>& vec)" << std::endl;
}
 
void func1(std::list<int>& list)
{
    std::cout << "void func1(std::list<int>& list)" << std::endl;
}
 
template<typename T>
void func2(std::vector<T>& vec)
{
    std::cout << "void func2(std::vector<T>& vec)" << std::endl;
}
template<typename T>
void func2(std::list<T>& list)
{
    std::cout << "void func2(std::list<T>& list)" << std::endl;
}
 
template<template<typename, typename > class C, typename T, typename A>
void func3(C<T, A>& cont)
{
    std::cout << "void func3(C<T, A>& cont)" << std::endl;
}
 
#include <iterator>
#include <type_traits>
 
template<typename IT>
typename std::enable_if<
        std::is_base_of<std::bidirectional_iterator_tag,
                typename std::iterator_traits<IT>::iterator_category>::value>::type func4(
        IT begin, IT end)
{
    std::cout << "func4(IT begin, IT end)" << std::endl;
}
 
int main()
{
    std::vector<int> vec;
    std::list<int> list;
    func1(vec);
    func1(list);
    func2(vec);
    func2(list);
    func3(vec);
    func3(list);
    func4(std::begin(vec), std::end(vec));
    func4(std::begin(list), std::end(list));
}
2
GbaLog-
Любитель чаепитий
3164 / 1470 / 465
Регистрация: 24.08.2014
Сообщений: 5,200
Записей в блоге: 1
Завершенные тесты: 2
14.10.2016, 22:49 #6
Цитата Сообщение от Nosey Посмотреть сообщение
C++
1
template<template<typename, typename > class C, typename T, typename A>
Из книги Джосаттиса:
Цитата Сообщение от algostuff.hpp
C++
1
2
3
4
5
6
7
8
9
10
// INSERT_ELEMENTS(collection,int first,int last)
// - заполняет коллекцию значениями от first до last
// - ЗАМЕЧАНИЕ: диапозон НЕ ЯВЛЯЕТСЯ полуоткрытым
template<typename T>
inline void INSERT_ELEMENTS(T& coll,int first,int last)
{
    for(int i = first; i <= last; i++) {
        coll.insert(coll.end(),i);
    }
}
Почему у Вас по-другому? В чём различие?
0
Nosey
1350 / 401 / 144
Регистрация: 22.10.2014
Сообщений: 863
Завершенные тесты: 2
14.10.2016, 22:58 #7
Цитата Сообщение от GbaLog- Посмотреть сообщение
В чём прикол?
Конкретно в данном случае, с одной стороны template головного мозга , с другой стороны в стандартной библиотеке нету container_traits, что несколько усложняет работу с Cont по сравнению с Cont<T>. Но повторюсь это "template головного мозга". )
1
Dassis
0 / 0 / 1
Регистрация: 11.09.2015
Сообщений: 83
15.10.2016, 00:03  [ТС] #8
Спасибо?

Добавлено через 29 минут
и вопрос из той же оперы, можно ли сделать цикл который определяет container вектор или список?
0
Nosey
1350 / 401 / 144
Регистрация: 22.10.2014
Сообщений: 863
Завершенные тесты: 2
15.10.2016, 00:23 #9
Цитата Сообщение от Dassis Посмотреть сообщение
можно ли сделать цикл который определяет container вектор или список?
Можно, только я не понял что именно вы хотите. Перефразируйте вопрос, и вообще хорошо если псевдокодом.
0
Dassis
0 / 0 / 1
Регистрация: 11.09.2015
Сообщений: 83
15.10.2016, 00:33  [ТС] #10
Nosey, итак дали задачу следующую - разработать функцию сортировки для вектора [], потом для вектора через at() и для forward_list, (один алгоритм) вот и пытаюсь что нить написать

Добавлено через 2 минуты
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
template <class T>
void sort(std::vector<T> &vct, const char* argv[], std::forward_list <int>fl, const int chs)
{
    std::string asc = "ascending";
    std::string des = "descending";
    int size = 0;
    T tmp = 0;
    size = vct.size();
    if (argv[2] == asc)
    {
        if (chs == 0) {
            for (int i = 0; i < size - 1; ++i)
            {
                for (int j = 0; j < size - 1; ++j)
                {
                    if (vct[j + 1] < vct[j])
                    {
                        tmp = vct[j + 1];
                        vct[j + 1] = vct[j];
                        vct[j] = tmp;
 
                    }
                }
            }
            printVec(vct);
        }
        if (chs == 1) {
            for (int i = 0; i < size - 1; ++i)
            {
                for (int j = 0; j < size - 1; ++j)
                {
                    if (vct.at(j + 1) < vct.at(j))
                    {
                        tmp = vct.at(j + 1);
                        vct.at(j + 1) = vct.at(j);
                        vct.at(j) = tmp;
                    }
                }
            }
            printVec(vct);
        }
        if (chs == 2) {
            for (std::forward_list<int>::iterator it = fl.begin(); it != fl.end(); it++)
            {
                for (std::forward_list<int>::iterator itr = it; itr != fl.end(); itr++)
                {
                    if (*it > *itr)
                    {
                        tmp = *it;
                        *it = *itr;
                        *itr = tmp;
                    }
                }
            }
            printForward(fl);
        }
    }
    if (argv[2] == des) {
        if (chs == 0) {
            for (int i = 0; i < size - 1; ++i)
            {
                for (int j = 0; j < size - 1; ++j)
                {
                    if (vct[j + 1] > vct[j])
                    {
                        tmp = vct[j + 1];
                        vct[j + 1] = vct[j];
                        vct[j] = tmp;
 
                    }
                }
            }
            printVec(vct);
        }
        if (chs == 1) {
            for (int i = 0; i < size - 1; ++i)
            {
                for (int j = 0; j < size - 1; ++j)
                {
                    if (vct.at(j + 1) > vct.at(j))
                    {
                        tmp = vct.at(j + 1);
                        vct.at(j + 1) = vct.at(j);
                        vct.at(j) = tmp;
                    }
                }
            }
            printVec(vct);
        }
        if (chs == 2) {
            for (std::forward_list<int>::iterator it = fl.begin(); it != fl.end(); it++)
            {
                for (std::forward_list<int>::iterator itr = it; itr != fl.end(); itr++)
                {
                    if (*it < *itr)
                    {
                        tmp = *it;
                        *it = *itr;
                        *itr = tmp;
                    }
                }
            }
            printForward(fl);
        }
    }
    else if (argv[2] != asc && argv[2] != des)
    {
        std::cerr << "!!invalid arguments!!\n";
        exit(1);
    }
}
сам код 3 сортировок но через костыли, а их надо поместить в один алгоритм.

Добавлено через 1 минуту
и спрашивал я про ну например если if (vector) {
C++
1
2
3
}
if (list) {
}
0
Nosey
1350 / 401 / 144
Регистрация: 22.10.2014
Сообщений: 863
Завершенные тесты: 2
15.10.2016, 01:04 #11
Цитата Сообщение от Dassis Посмотреть сообщение
и спрашивал я про ну например если if (vector) {
}
if (list) {
}
Если такой подход использовать. т.е. подход в котором алгоритм сортировки зависит от интерфейса контейнера, то используйте перегрузку(мои верхние функции func1 || func2). Немного псевдокоду для понимания перегрузки:
Код
void sortImpl(std::vector<T> &vct) {}
void sortImpl(std::forward_listT> &vct) {}
void sort(std::vector<T> &vct,std::forward_list <int>fl)//псевдокод
{
if (vct) sortImpl(vct);//псевдокод
if (fl) sortImpl(fl);//псевдокод
}

//предполагаемые вами вызовы вашей функции:
sort(vector);//псевдокод
sort(null,list);//псевдокод
// эквивалентены
sortImpl(vector);
sortImpl(list);
Если же алгоритм сортировки не зависит от контейнера, т.е. возможности всех требуемых контейнеров удовлетворяют требования выбранного алгоритма, то можно написать общий шаблон, см мои верхние функции func3 || func4 || фукнцию от GbaLog-.

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

П.с. оформляйте код соответствующими тегами.
1
Dassis
0 / 0 / 1
Регистрация: 11.09.2015
Сообщений: 83
15.10.2016, 01:22  [ТС] #12
Nosey, спасибо за обьяснения, но тогда возникаю вопросы, как передать в функцию именно vector.at() и как реализовать тогда пузырек если в первом случае вектор а во 2 итераторы у них даже циклы разные
0
Nosey
1350 / 401 / 144
Регистрация: 22.10.2014
Сообщений: 863
Завершенные тесты: 2
15.10.2016, 09:13 #13
Цитата Сообщение от Dassis Посмотреть сообщение
как передать в функцию именно vector.at()
Еще раз :
Если алгоритм сортировки использует различные интерфейсы для разных контейнеров, как например для вектора vec.at, а для листа forward_iterator, то вам нужно писать "две" функции (можно использовать механизм перегрузки функций или специализации шаблонной функции), у этих функций будет одно название, одинаковый вызов, но разное содержимое функции для разных аргументов. ( Прочитайте по этой теме книжку, вы очень быстро разберётесь)

Если же вам не обязательно использовать at (к тому же совершенно бесполезный, поскольку в вашем коде есть проверка ind < vec.size(), такая же гарантия присутствует в вашем алгоритме на итераторах (it != itEnd)). То используйте шаблон функции, реализующий сортировку и использующий общий интерфейс, в частности forward_iterator ибо форвад_лист и вектор позволяют инкрементировать итераторы.
т.е. берём ваш последний код сортировки:
Цитата Сообщение от Dassis Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
            for (std::forward_list<int>::iterator it = fl.begin(); it != fl.end(); it++)
            {
                for (std::forward_list<int>::iterator itr = it; itr != fl.end(); itr++)
                {
                    if (*it < *itr)
                    {
                        tmp = *it;
                        *it = *itr;
                        *itr = tmp;
                    }
                }
            }
И запаковываем его в функцию от GbaLog-.
C++
1
2
3
4
5
template< typename Cont >
void func( Cont& container )
{
    // some code
}
для этого в вашей реализации все типы(std::forward_list<int>::iterator) нужно сделать зависимыми от параметра шаблона(Cont), т.е. иетраторы будут Cont::iterator, а tmp будет типом Cont::value_type.
0
Dassis
0 / 0 / 1
Регистрация: 11.09.2015
Сообщений: 83
15.10.2016, 10:41  [ТС] #14
Nosey, ок, спасибо, стало понятнее

Добавлено через 1 час 13 минут
Nosey, я перегрузил функцию сортировки и она работает для вектора и для списка, но последний вопрос а как пожно сделать так чтобы я передавал в функцию vector.at()
0
GbaLog-
Любитель чаепитий
3164 / 1470 / 465
Регистрация: 24.08.2014
Сообщений: 5,200
Записей в блоге: 1
Завершенные тесты: 2
15.10.2016, 10:45 #15
Цитата Сообщение от Dassis Посмотреть сообщение
передавал в функцию vector.at()
Вы не сможете передать в функцию vector::at(),
потому что это функция-член, а не переменная какая-нибудь.
http://en.cppreference.com/w/cpp/container/vector/at
0
Nosey
1350 / 401 / 144
Регистрация: 22.10.2014
Сообщений: 863
Завершенные тесты: 2
15.10.2016, 12:23 #16
Dassis, Я очень не уверен что преподаватель от вас хочет этого.

Но, хозяин барин:
C++
1
2
3
4
5
6
7
8
9
10
11
12
//typedef typename std::vector<int>::reference (std::vector<int>::* VectorMemberAtPointer)(std::vector<int>::size_type);
using VectorMemberAtPointer = typename std::vector<int>::reference (std::vector<int>::*)(std::vector<int>::size_type);
void f(VectorMemberAtPointer pointer, std::vector<int>& vec)
{
    std::cout << (vec.*pointer)(0) << std::endl;
}
 
int main()
{
    std::vector<int> vec { 10, 2, 3, 5, 7 };
    f(&std::vector<int>::at, vec);
}
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7045 / 3346 / 452
Регистрация: 04.12.2011
Сообщений: 9,306
Записей в блоге: 5
15.10.2016, 16:35 #17
Цитата Сообщение от Dassis Посмотреть сообщение
как реализовать тогда пузырек если в первом случае вектор
Dassis, контейнеры stl и самописные методы сортировки вроде выбора, вставки, всплытия, это материал разных периодов. Совмещение, говорит о странном.
В векторе как и в массиве нужно искать используя бинарный поиск. А список можно только последовательным перебором пройти. Это разные алгоритмы и перегрузка, это то, что нужно.
Цитата Сообщение от Dassis Посмотреть сообщение
стало понятнее
и
Цитата Сообщение от Dassis Посмотреть сообщение
как можно сделать так чтобы я передавал в функцию vector.at()
трудно совместимые утверждения.
Именно перегрузка и поможет разрулить вариант когда члены не совпадают, а это именно тот случай, - у списка нет .at(). Или Вы не знаете как работает перегрузка? Кроме того, не надо прередавать .at():
Вам показали как передать ссылку на экземпляр вектора/списка? В чём проблема с вызовом функции-члена? Она же на экземпляре и вызывается. Иначе нужно связать экземпляр как-то извращенно. И это возможно, но зачем?
Это ещё одно подтверждения странного построения курса. Изучать контейнеры/классы STL нужно после твердого ознакомления с ООП. А сортировке пузырьком нечего делать рядом с вектором и списком.
Моё мнение, - держитесь совета:
Цитата Сообщение от Nosey Посмотреть сообщение
используйте перегрузку(мои верхние функции func1 || func2)
1
15.10.2016, 16:35
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.10.2016, 16:35

Что-то интересное. Или программа, которая принимает либо 1, либо 2 числа
Программа - консольное приложение, в качестве параметров при вызове принимает...

Проверка открытия файла либо работает, либо уходит в бесконечность
string A=Enterway('t');//функция ввода адреса файла fstream str(A.c_str(),...

Никак не могу найти ошибку, должен сосздать матрицу либо из звездочеку либо из пробелов
#include &lt;iostream&gt; #include &lt;cmath&gt; #include &lt;ctime&gt; using namespace std;...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru