Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
7 / 7 / 3
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
1

STL Iterators

07.08.2012, 19:13. Показов 2478. Ответов 21
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Допустим есть проект

ContainerTemplateFunction_hpp
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
#ifndef ContainerTemplateFunction_hpp   // Preprocessor gates
#define ContainerTemplateFunction_hpp
    
        #include <list>
        #include <vector>
        #include <iostream>
        #include <map> 
 
        template <typename T> 
        double Sum (std::list<T>& MyList)
            {
 
                double sum_of_MyList_elements = 0;
 
                std::list<T>::iterator iMyListIterator = MyList.begin();    
                
                
                    while (iMyListIterator != MyList.end()) // A loop that iterates MyList 
                        {
                            sum_of_MyList_elements += *(iMyListIterator++);
                        }
                return sum_of_MyList_elements ; 
            }
 
 
 
        template  <typename T> 
        double Sum (std::vector<T>& MyVector)
            {
                double sum_of_MyVector_elements = 0;
 
                std::vector<T>::iterator iMyVectorIterator = MyVector.begin();  
 
                    while (iMyVectorIterator!=MyVector.end())
                        {
                            sum_of_MyVector_elements += *(iMyVectorIterator++);
                        }
                return sum_of_MyVector_elements;
            }
 
        template <typename T, typename T1> 
        double Sum ( std::map<T, T1>& MyMap)
            {
                double sum_of_MyMap_elements =0 ;
 
                std::map<T, T1>::iterator iMyMapIterator=MyMap.begin();
 
                    while (iMyMapIterator!=MyMap.end())
                        {
                            sum_of_MyMap_elements += iMyMapIterator++ -> second;
                        }
                return sum_of_MyMap_elements;
            }
 
            template <typename FirstSummandContainer,typename SecondSummandContainer>
 
            double Sum (FirstSummandContainer& ObjFirstSummandContainer, 
                SecondSummandContainer& ObjSecondSummandContainer)
                {
                    return Sum(ObjFirstSummandContainer) + Sum(ObjSecondSummandContainer);
                }
 
 
 
 
#endif


main.cpp
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
#include "ContainerTemplateFunction.hpp"
 
int main() 
    {
 
        std::cout   << "\n\n\t\t    --- TEST OF SUM --- " 
                            << "\n\t\t     --- *LIST* --- \n " ;
 
 
        std::cout << "----- sum of list container ----- "<< std::endl;
 
        std::list <int> My_TestSum_List ; 
        for (int i=0;i<10;i++) // filling <list > of elements 
            {
                My_TestSum_List.push_back(i);
            }
 
        std::list<int>::iterator iMy_List_Iterator = My_TestSum_List.begin();
        
        std::cout << "-----Print without accumlating------" << std::endl;
            for (iMy_List_Iterator = My_TestSum_List.begin();
                 iMy_List_Iterator != My_TestSum_List.end() ; ++iMy_List_Iterator)
                {
                    std::cout << (*iMy_List_Iterator) << ", ";
                }
            std::cout << std::endl;
            std::cout << "\ntest of sum function for list :" << Sum(My_TestSum_List)  << std::endl;
 
// __________________________________________________________________________________________
 
            std::cout   << "\n\n\t\t    --- TEST OF SUM --- " 
                            << "\n\t\t      --- *VECTOR* --- \n " ;
        
        std::vector <int> My_TestSum_Vector;
 
            for (int i=0;i<10;i++) 
                {
                    My_TestSum_Vector.push_back(i);
                }
 
        std::vector<int>::iterator iMy_Vector_Iterator = My_TestSum_Vector.begin();
    
            std::cout << "-----Print without accumlating------" << std::endl;
            for (iMy_Vector_Iterator  = My_TestSum_Vector.begin() ; 
                 iMy_Vector_Iterator != My_TestSum_Vector.end(); ++iMy_Vector_Iterator)
                {
                    std::cout << (*iMy_Vector_Iterator) << ", ";
                }
            std::cout << "\ntest of sum function for vector  :"<<   Sum(My_TestSum_Vector)  << std::endl;
// __________________________________________________________________________________________
 
            std::cout       << "\n\n\t\t    --- TEST OF SUM --- " 
                            << "\n\t\t       --- *MAP* --- \n " ;
    
    
        std::map <double, double > My_SumTest_Map;
 
        for (int i=0;i<10;i++) My_SumTest_Map[i] = i*10;
 
        std::map<double, double>::iterator iMy_Map_Iterator = My_SumTest_Map.begin();
    
        std::cout << "\n sum of all MyMap elements  is :"   <<  Sum(My_SumTest_Map) ;
 
        std::cout << "\n-----Print without accumlating------" << std::endl;
 
            for (iMy_Map_Iterator = My_SumTest_Map.begin();
                iMy_Map_Iterator!=My_SumTest_Map.end(); ++iMy_Map_Iterator)
//              for (auto)
                {
                    std::cout   << "\n["    << iMy_Map_Iterator->first  
                                << "] -> " 
                                << "("      << iMy_Map_Iterator->second<<")";
                }
 
            
// __________________________________________________________________________________________
            std::cout   << "\n\n\t\t    --- TEST OF SUM --- " 
                            << "\n\t\t   --- *TWO CONTAINER.* --- \n " ;
 
            std::cout   << "\n Sum between two containers <vector> and <map> is :" 
                        <<Sum(My_TestSum_Vector,My_SumTest_Map) 
 
                        << "\n Sum between two containers <vector> and <list> is :" 
                        <<Sum(My_TestSum_Vector,My_TestSum_List) 
 
                        << "\n Sum between two containers <list> and <map> is :" 
                        <<Sum(My_TestSum_List,My_SumTest_Map) ; 
                        
 
            std::cout << "\n\n\n\t"; 
        return 0;
    }


Хочется чтобы
в ContainerTemplateFunction.hpp было не 3 шаблона для каждого контейнера отдельно, а один шаблон...
как сделать совместный шаблон для вектора и листа более менее понятно как сделать чтобы для карты (мап ) (map) вместе с вектором и листом был один шаблон (ну типа там же 2 аргумента а не один для как для листа и вектора ) подскажите плиз )
Заранее спасибо !
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.08.2012, 19:13
Ответы с готовыми решениями:

Vector iterators incompatible
Добрый вечер! Прошу подсказки начинающему! имеется код: ... ......

iterators & file
можно ли считывать итераторами с файла типу так: #include &lt;iostream&gt; #include &lt;fstream&gt; #include...

Map/set iterators are incompatible
void Delete(int a , int b) { multiset &lt;double&gt; ::iterator First, Last; multiset &lt;double&gt;...

Оибка vector iterators incompatible ?
привет всем ! вот код class rgb2hsl { public: rgb2hsl(vector&lt;int&gt; r, vector&lt;int&gt; g ,...

21
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
07.08.2012, 19:42 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
#include <iostream>
#include <vector>
#include <map>
 
template<typename Iterator>
double get_el(Iterator i, const typename Iterator::value_type&)
{
   return *i;
}
 
template<typename T, typename T2, typename Iterator>
double get_el(Iterator i, const std::pair<const T, T2>&)
{
   return i->second;
}
 
template<typename Container>
double sum(const Container& cnt)
{
   typedef typename Container::const_iterator c_iter;
   double sum = 0;
   for (c_iter i = cnt.begin();
        i != cnt.end();
        ++i)
   {
      sum += get_el(i, *i);
   }
   return sum;
}
 
int main()
{
   std::vector<double> v = {1,2};
   std::cout << sum(v) << std::endl;
   std::map<int, double> m = 
   {
     std::make_pair(1, 1.0),
     std::make_pair(2, 2.0)
   };
   std::cout << sum(m) << std::endl;
}
http://liveworkspace.org/code/... c36c597b22

Или сделать функцию от двух итераторов, но все равно нужно будет некое подобие перегрузок функции get_el.
1
4773 / 2582 / 894
Регистрация: 29.11.2010
Сообщений: 5,590
07.08.2012, 22:39 3
Цитата Сообщение от ForEveR Посмотреть сообщение
Или сделать функцию от двух итераторов
Функция от двух итераторов самое то. Уже есть, конечно, std::accumulate, но можно и навелосипедить.

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
#include <iostream>
#include <utility>
#include <map>
 
// велосипед для std::plus
struct binaryOperationSum {
  template <class T>
  T operator()(const T &a, const T &b) {
    return a + b;
  }
};
 
// функтор для сложения второго значения у std::pair
struct binaryOperationSumOfPair {
  template <class T>
  double operator()(double &a, const T &b) {
    return a + b.second;
  }
};
 
// велосипед для std::sum
template <class StartIterator, class FinishIterator, class T,
  class BinaryOperation>
T sum(StartIterator begin, FinishIterator end,
  T initialValue, BinaryOperation operation) {
  while (begin != end)
    initialValue = operation(initialValue, *begin++);
  return initialValue;
}
 
// велосипед для std::sum с дефолтной бинарной операцией 
template <class StartIterator, class FinishIterator, class T>
T sum(StartIterator begin, FinishIterator end, T initialValue) {
  return sum(begin, end, initialValue, binaryOperationSum());
}
 
int main(int argc, char **argv) {
  std::map<int, double> a;
  a[0] = 1.25;
  a[1] = 0.75;
  a[2] = 0.23;
  std::cout << sum(a.begin(), a.end(), 0.0, binaryOperationSumOfPair());
  return 0;
}
1
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
07.08.2012, 23:56 4
lemegeton, Ну accumulate-то да конечно.
1
7 / 7 / 3
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
09.08.2012, 18:58  [ТС] 5
Цитата Сообщение от ForEveR Посмотреть сообщение
lemegeton, Ну accumulate-то да конечно.
Что то как всего много...
Короче задание звучит так
В задании посказка как надо делать :

Создайте темплейт функцию назовите ее Sum() которая принимает темплейт аргумент как импут и возвращает double. Темплейт аргумент будет контейнер.

В инплементации гет итерейтер ((T::const_iterator)) для конца. Затем создайте цикл который будет итерейтить контейнер T и складывать все элементы. В финале ретернте сумму (return sum )

В мейне вызовете Sum() функциию для разных контейнеров вектор лит карта

Sum() функция вычисляет сумму комплит контейнера. Так же создайте Sum() функцию которая вычисляет сумму между двумя итераторами. И функцию которая использует темплейт аргумент для итерации типа и доступа к друм итераторам старт и конец итератор...
Блин по русски как то криво звучит вообщем вот оригинал

C++
1
2
3
4
5
6
7
8
9
10
11
12
вот это походу если я правильно понимаю 
 
// велосипед для std::sum с дефолтной бинарной операцией 
    template <class StartIterator, class FinishIterator, class T>
    T sum(StartIterator begin, FinishIterator end, T initialValue) 
        {
          return Sum(begin, end, initialValue, binaryOperationSum());
        }
 
-> Also create a Sum() function that calculates the sum between two iterators. 
The function then uses the template argument for the iterator type and accepts 
two iterators, the start and end iterator.
Миниатюры
STL Iterators  
0
7 / 7 / 3
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
09.08.2012, 19:15  [ТС] 6
Так ладно попробую разобраться
0
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
09.08.2012, 19:45 7
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
#include <iostream>
 
#include <vector>
#include <list>
#include <deque>
 
 
template <typename Iterator>
double
Sum( Iterator first, Iterator last )
{
    double ret = 0.0;
 
    while( first != last )
        ret += *first++;
 
    return ret;
}
 
 
int
main()
{
    // typedef std::vector< double > double_container_t;
    // typedef std::list< double > double_container_t;
    typedef std::deque< double > double_container_t;
 
    double_container_t nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -10 };
 
    std::cout << "sum = " << Sum( nums.begin(), nums.end() ) << '\n';
 
    return 0;
}
Так? :-)
1
~ Эврика! ~
1256 / 1005 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
09.08.2012, 19:50 8
Лучший ответ Сообщение было отмечено как решение

Решение

Уроки литературного перевода
Используя итераторы, мы можем перемещаться по контейнеру STL, ничего не зная о самом контейнере. В этом упражнении вам предлагается реализовать функцию, вычисляющую сумму элементов типа double, хранимых в контейнере.
  • Создайте шаблонную функцию Sum(), которая принимает шаблонный аргумент типа T и возвращает double. Этот аргумент — это контейнер.
  • В функции получите итератор (T::const_iterator), указывающий на конец контейнера. Затем пройдитесь в цикле по контейнеру и сложите значения его элементов. Наконец, верните из функции сумму.
  • В главной программе вызовите Sum() для контейнера, отличающегося от применённого в предыдущем упражнении.
Данная функция Sum() вычисляет сумму всего контейнера. Также реализуйте Sum(), которая бы вычисляла сумму элементов между двумя итераторами. Шаблонный тип функции будет типом двух принимаемых итераторов, указывающих на начало и конец суммируемого региона.
5
7 / 7 / 3
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
09.08.2012, 20:11  [ТС] 9
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
#include <iostream>
#include <vector>
#include <map>
 
template<typename Iterator>
double get_el(Iterator i, const typename Iterator::value_type&)
{
   return *i;
}
 
template<typename T, typename T2, typename Iterator>
double get_el(Iterator i, const std::pair<const T, T2>&)
{
   return i->second;
}
 
template<typename Container>
double sum(const Container& cnt)
{
   typedef typename Container::const_iterator c_iter;
   double sum = 0;
   for (c_iter i = cnt.begin(); i != cnt.end();  ++i)
       {
          sum += get_el(i, *i);
       }
   return sum;
}
 
int main()
{
 
 
    std::vector <int> My_TestSum_Vector;
 
            for (int i=0;i<10;i++) 
                {
                    My_TestSum_Vector.push_back(i);
                }
 
            
 
         std::map<int, double> My_SumTest_Map = 
                           {
                             std::make_pair(1, 1.0), std::make_pair(2, 2.0)
                           };
  
   std::cout << "vector" << sum(My_TestSum_Vector) << std::endl;
 
  
   std::cout <<"map sum " << sum(My_SumTest_Map) << std::endl;
}

1>------ Build started: Project: L7_ex2_from_forum, Configuration: Debug Win32 ------
1> main.cpp
1>main.cpp(43): error C2552: 'My_SumTest_Map' : non-aggregates cannot be initialized with initializer list
1> 'std::map<_Kty,_Ty>' : Types with a base are not aggregate
1> with
1> [
1> _Kty=int,
1> _Ty=double
1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Добавлено через 8 минут
Цитата Сообщение от talis Посмотреть сообщение
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
#include <iostream>
 
#include <vector>
#include <list>
#include <deque>
 
 
template <typename Iterator>
double
Sum( Iterator first, Iterator last )
{
    double ret = 0.0;
 
    while( first != last )
        ret += *first++;
 
    return ret;
}
 
 
int
main()
{
    // typedef std::vector< double > double_container_t;
    // typedef std::list< double > double_container_t;
    typedef std::deque< double > double_container_t;
 
    double_container_t nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -10 };
 
    std::cout << "sum = " << Sum( nums.begin(), nums.end() ) << '\n';
 
    return 0;
}
Так? :-)
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
#include <iostream>
 
#include <vector>
#include <list>
#include <map>
 
 
template <typename Iterator>
double
Sum( Iterator first, Iterator last )
{
    double ret = 0.0;
 
    while( first != last )
        ret += *first++;
 
    return ret;
}
 
 
int
main()
{
    // typedef std::vector< double > double_container_t;
    // typedef std::list< double > double_container_t;
    typedef std::map< double,double > double_container_t;
 
     double_container_t MyContainer;
 
            for (int i=0;i<10;i++) 
                {
                    //MyContainer.push_back(i);
                    MyContainer[i] = i*10; 
                }
 
    std::cout << "sum = " << Sum( MyContainer.begin(), MyContainer.end() ) << '\n';
 
    return 0;
 
}
errors
1>------ Build started: Project: L7_ex2_from_forum, Configuration: Debug Win32 ------
1> main.cpp
main.cpp(15): error C2677: binary '+=' : no global operator found which takes type 'std:air<_Ty1,_Ty2>' (or there is no acceptable conversion)
1> with
1> [
1> _Ty1=const double,
1> _Ty2=double
1> ]
1> main.cpp(36) : see reference to function template instantiation 'double Sum<std::_Tree_iterator<_Mytree>>(Iterator,Iterator)' being compiled
1> with
1> [
1> _Mytree=std::_Tree_val<std::_Tmap_traits<double,double,std::less<double>,std::al locator<std:air<const double,double>>,false>>,
1> Iterator=std::_Tree_iterator<std::_Tree_val<std::_Tmap_traits<double,double,std: :less<double>,std::allocator<std:air<const double,double>>,false>>>
1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


для map не работает
0
~ Эврика! ~
1256 / 1005 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
09.08.2012, 20:29 10
Цитата Сообщение от Leeto Посмотреть сообщение
для map не работает
Естественно, потому что итератор по map по operator* возвращает пары, а не единичные значения. Они органически несовместимы.

Как решать? Да что-то ничего умнее и красивее адаптера в голову не приходит. Он позволит совместить несовместимое:
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
#include <iostream>
 
#include <vector>
#include <list>
#include <map>
 
template <typename Iterator>
double
Sum( Iterator first, Iterator last )
{
    double ret = 0.0;
 
    while( first != last )
        ret += *first++;
 
    return ret;
}
 
template <class T1, class T2>
class MapAdapter {
  typename std::map<T1, T2>::iterator iterator;
public:
  MapAdapter(const typename std::map<T1, T2>::iterator &iterator_):
    iterator(iterator_) {}
 
  MapAdapter<T1, T2>& operator++()
  {
    iterator++;
    return this;
  }
 
  MapAdapter<T1, T2> operator++(int bork)
  {
    return MapAdapter<T1, T2>(++iterator);
  }
 
  T2 operator*()
  {
    return (*iterator).second;
  }
 
  bool operator==(const MapAdapter<T1, T2> &other)
  {
    return this->iterator == other.iterator;
  }
 
  bool operator==(const typename std::map<T1, T2>::iterator &other)
  {
    return this->iterator == other;
  }
 
  bool operator!=(const MapAdapter<T1, T2> &other)
  {
    return !MapAdapter<T1, T2>::operator==(other);
  }
 
  bool operator!=(const typename std::map<T1, T2>::iterator &other)
  {
    return !MapAdapter<T1, T2>::operator==(other);
  }
};
 
int
main()
{
    // typedef std::vector< double > double_container_t;
    // typedef std::list< double > double_container_t;
    typedef std::map< double,double > double_container_t;
 
     double_container_t MyContainer;
            for (int i=0;i<10;i++) 
                {
                    MyContainer[i] = i*10; 
                }
 
    std::cout << "sum = " << Sum(MapAdapter<double, double>(MyContainer.begin()), MapAdapter<double, double>(MyContainer.end())) << '\n';
    return 0;
}
2
7 / 7 / 3
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
09.08.2012, 20:43  [ТС] 11
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Естественно, потому что итератор по map по operator* возвращает пары, а не единичные значения. Они органически несовместимы.

Как решать? Да что-то ничего умнее и красивее адаптера в голову не приходит. Он позволит совместить несовместимое:
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
#include <iostream>
 
#include <vector>
#include <list>
#include <map>
 
template <typename Iterator>
double
Sum( Iterator first, Iterator last )
{
    double ret = 0.0;
 
    while( first != last )
        ret += *first++;
 
    return ret;
}
 
template <class T1, class T2>
class MapAdapter {
  typename std::map<T1, T2>::iterator iterator;
public:
  MapAdapter(const typename std::map<T1, T2>::iterator &iterator_):
    iterator(iterator_) {}
 
  MapAdapter<T1, T2>& operator++()
  {
    iterator++;
    return this;
  }
 
  MapAdapter<T1, T2> operator++(int bork)
  {
    return MapAdapter<T1, T2>(++iterator);
  }
 
  T2 operator*()
  {
    return (*iterator).second;
  }
 
  bool operator==(const MapAdapter<T1, T2> &other)
  {
    return this->iterator == other.iterator;
  }
 
  bool operator==(const typename std::map<T1, T2>::iterator &other)
  {
    return this->iterator == other;
  }
 
  bool operator!=(const MapAdapter<T1, T2> &other)
  {
    return !MapAdapter<T1, T2>::operator==(other);
  }
 
  bool operator!=(const typename std::map<T1, T2>::iterator &other)
  {
    return !MapAdapter<T1, T2>::operator==(other);
  }
};
 
int
main()
{
    // typedef std::vector< double > double_container_t;
    // typedef std::list< double > double_container_t;
    typedef std::map< double,double > double_container_t;
 
     double_container_t MyContainer;
            for (int i=0;i<10;i++) 
                {
                    MyContainer[i] = i*10; 
                }
 
    std::cout << "sum = " << Sum(MapAdapter<double, double>(MyContainer.begin()), MapAdapter<double, double>(MyContainer.end())) << '\n';
    return 0;
}

Блин спасибо конечно большое!!! это вообще код героя 80 уровня ...
Но блин по заданию там должен быть один аргумент that accepts the template argument T as input and returns a double. НЕ argumentS, а the argument...

Короче походу накосячали с составлением задания что то я смотрю не кто не делает чтоб мап вектор и лист в одном темплейте был...

короче как сделать чтоб вектор и лист был в одном темплейте и принимал аргумент контейнер

тут был хороший вариант спасибо товарищу !

Но как это объединить в один темплейт

спасибо товарищу !
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
template<typename Iterator>
double get_el(Iterator i, const typename Iterator::value_type&)
{
   return *i;
}
 
 
template<typename Container>
double Sum(const Container& cnt)
{
   typedef typename Container::const_iterator c_iter;
   double Sum = 0;
   for (c_iter i = cnt.begin(); i != cnt.end(); ++i)
       {
          Sum += get_el(i, *i);
       }
   return Sum;
}
 
 
int
main()
{
    // typedef std::vector< double > double_container_t;
     typedef std::list< double > double_container_t;
    //typedef std::map< double,double > double_container_t;
 
     double_container_t MyContainer;
 
            for (int i=0;i<10;i++) 
                {
                    MyContainer.push_back(i);
                    //MyContainer[i] = i*10; 
                }
            
    std::cout << "sum = " << Sum(MyContainer ) << '\n';
 
    return 0;
 
}




Или вот допустим то что я нахреначил, как сделать так чтоб это один был тимплейт (лучше конечно этот переделать)
то на что меня хватило пока
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
template <typename T> 
        double Sum (std::list<T>& MyList)
            {
 
                double sum_of_MyList_elements = 0;
 
                std::list<T>::iterator iMyListIterator = MyList.begin();    
                
                
                    while (iMyListIterator != MyList.end()) // A loop that iterates MyList 
                        {
                            sum_of_MyList_elements += *(iMyListIterator++);
                        }
                return sum_of_MyList_elements ; 
            }
 
 
 
        template  <typename T> 
        double Sum (std::vector<T>& MyVector)
            {
                double sum_of_MyVector_elements = 0;
 
                std::vector<T>::iterator iMyVectorIterator = MyVector.begin();  
 
                    while (iMyVectorIterator!=MyVector.end())
                        {
                            sum_of_MyVector_elements += *(iMyVectorIterator++);
                        }
                return sum_of_MyVector_elements;
            }
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
09.08.2012, 20:57 12
Leeto, Это и есть 1 темплейт. Для любого контейнера он используется. Разнится только функция получения элемента, что логично, потому как итератор мапы указывает на
C++
1
std::pair<const Key, Value>
(так было в том варианте, который я предоставил изначально, куда дели перегрузку доставания элемента из итератора мапы?)

Добавлено через 8 минут
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
#include <iostream>
#include <vector>
#include <map>
 
template<typename Iterator>
double get_el(Iterator i, const typename Iterator::value_type&)
{
   return *i;
}
 
template<typename T, typename T2, typename Iterator>
double get_el(Iterator i, const std::pair<const T, T2>&)
{
   return i->second;
}
 
template<typename Container>
double sum(const Container& cnt)
{
   typedef typename Container::const_iterator c_iter;
   double sum = 0;
   for (c_iter i = cnt.begin();
        i != cnt.end();
        ++i)
   {
      sum += get_el(i, *i);
   }
   return sum;
}
 
int main()
{
   double array[] = {1, 2};
   std::vector<double> v(array, array + sizeof(array) / sizeof(*array));
   std::cout << sum(v) << std::endl;
   std::pair<int, double> map[] = 
   {
     std::make_pair(1, 1.0),
     std::make_pair(2, 2.0)
   };
   std::map<int, double> m(map, map + sizeof(map) / sizeof(*map));
   std::cout << sum(m) << std::endl;
}
http://liveworkspace.org/code/... 446df9bf30
1
7 / 7 / 3
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
09.08.2012, 21:06  [ТС] 13
Цитата Сообщение от ForEveR Посмотреть сообщение
Leeto, Это и есть 1 темплейт. Для любого контейнера он используется. Разнится только функция получения элемента, что логично, потому как итератор мапы указывает на
C++
1
std::pair<const Key, Value>
(так было в том варианте, который я предоставил изначально, куда дели перегрузку доставания элемента из итератора мапы?)

Добавлено через 8 минут
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
#include <iostream>
#include <vector>
#include <map>
 
template<typename Iterator>
double get_el(Iterator i, const typename Iterator::value_type&)
{
   return *i;
}
 
template<typename T, typename T2, typename Iterator>
double get_el(Iterator i, const std::pair<const T, T2>&)
{
   return i->second;
}
 
template<typename Container>
double sum(const Container& cnt)
{
   typedef typename Container::const_iterator c_iter;
   double sum = 0;
   for (c_iter i = cnt.begin();
        i != cnt.end();
        ++i)
   {
      sum += get_el(i, *i);
   }
   return sum;
}
 
int main()
{
   double array[] = {1, 2};
   std::vector<double> v(array, array + sizeof(array) / sizeof(*array));
   std::cout << sum(v) << std::endl;
   std::pair<int, double> map[] = 
   {
     std::make_pair(1, 1.0),
     std::make_pair(2, 2.0)
   };
   std::map<int, double> m(map, map + sizeof(map) / sizeof(*map));
   std::cout << sum(m) << std::endl;
}
http://liveworkspace.org/code/... 446df9bf30

main

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
#include <iostream>
#include <vector>
#include <map>
 
template<typename Iterator>
double get_el(Iterator i, const typename Iterator::value_type&)
{
   return *i;
}
 
template<typename T, typename T2, typename Iterator>
double get_el(Iterator i, const std::pair<const T, T2>&)
{
   return i->second;
}
 
template<typename Container>
double sum(const Container& cnt)
{
   typedef typename Container::const_iterator c_iter;
   double sum = 0;
   for (c_iter i = cnt.begin();
        i != cnt.end();
        ++i)
   {
      sum += get_el(i, *i);
   }
   return sum;
}
 
int main()
{
   double array[] = {1, 2};
   std::vector<double> v(array, array + sizeof(array) / sizeof(*array));
   std::cout << sum(v) << std::endl;
   std::pair<int, double> map[] = 
   {
     std::make_pair(1, 1.0),
     std::make_pair(2, 2.0)
   };
   std::map<int, double> m(map, map + sizeof(map) / sizeof(*map));
   std::cout << sum(m) << std::endl;
}


error

1>------ Build started: Project: L7_ex2_one_template, Configuration: Debug Win32 ------
1> main.cpp
1>\main.cpp(26): error C2668: 'get_el' : ambiguous call to overloaded function
1> main.cpp(12): could be 'double get_el<_Kty,_Ty,c_iter>(Iterator,const std:air<_Ty1,_Ty2> &)'
1> with
1> [
1> _Kty=int,
1> _Ty=double,
1> Iterator=c_iter,
1> _Ty1=const int,
1> _Ty2=double
1> ]
1> \main.cpp(6): or 'double get_el<c_iter>(Iterator,const std:air<_Ty1,_Ty2> &)'
1> with
1> [
1> Iterator=c_iter,
1> _Ty1=const int,
1> _Ty2=double
1> ]
1> while trying to match the argument list '(c_iter, const std:air<_Ty1,_Ty2>)'
1> with
1> [
1> _Ty1=const int,
1> _Ty2=double
1> ]
1> \main.cpp(42) : see reference to function template instantiation 'double sum<std::map<_Kty,_Ty>>(const Container &)' being compiled
1> with
1> [
1> _Kty=int,
1> _Ty=double,
1> Container=std::map<int,double>
1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========



у меня одного этот код не компелируется ?
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
09.08.2012, 21:17 14
Leeto, В VS тоже не работает... Ща придумаю что-нибудь.
1
7 / 7 / 3
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
09.08.2012, 21:26  [ТС] 15
Цитата Сообщение от ForEveR Посмотреть сообщение
Leeto, В VS тоже не работает... Ща придумаю что-нибудь.
Осталось разобраться с суммой между контейнерами
update code :
main
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
#include <iostream>
 
#include <vector>
#include <list>
#include <map>
 
 
 
template<typename Iterator>
double get_el(Iterator i, const typename Iterator::value_type&)
{
   return *i;
}
 
 
template<typename Container>
double Sum(const Container& cnt)
{
   typedef typename Container::const_iterator c_iter;
   double Sum = 0;
   for (c_iter i = cnt.begin(); i != cnt.end(); ++i)
       {
          Sum += get_el(i, *i);
       }
   return Sum;
}
 
        template <typename T, typename T1> 
        double Sum (const std::map<T, T1>& MyMap)
            {
                double sum_of_MyMap_elements = 0 ;
 
                std::map<T, T1>::const_iterator iMyMapIterator=MyMap.begin();
 
                    while (iMyMapIterator!=MyMap.end())
                        {
                            sum_of_MyMap_elements += iMyMapIterator++ -> second;
                        }
                return sum_of_MyMap_elements;
            }
 
            template <typename FirstSummandContainer,typename SecondSummandContainer>
            double Sum (FirstSummandContainer& ObjFirstSummandContainer, 
                SecondSummandContainer& ObjSecondSummandContainer)
                {
                    return Sum(ObjFirstSummandContainer) + Sum(ObjSecondSummandContainer);
                }
 
 
int
main()
{
    // typedef std::vector< double > double_container_t;
     typedef std::list< double > double_container_t;
    typedef std::map< double,double > double_M_container_t;
 
     double_container_t MyContainer;
     double_M_container_t MyMap;
            for (int i=0;i<10;i++) 
                {
                    MyContainer.push_back(i);
                    MyMap[i] = i*10; 
                }
 
 
            
    std::cout << "Vector or List sum = " << Sum(MyContainer ) << '\n';
    std::cout << "Map sum = " << Sum(MyMap ) << '\n';
 
    std::cout << "Map+Vecor or List sum = " << Sum(MyContainer, MyMap ) << '\n';
 
    return 0;
 
}


сейчас это выглядит вот так

C++
1
2
3
4
5
6
template <typename FirstSummandContainer,typename SecondSummandContainer>
            double Sum (FirstSummandContainer& ObjFirstSummandContainer, 
                SecondSummandContainer& ObjSecondSummandContainer)
                {
                    return Sum(ObjFirstSummandContainer) + Sum(ObjSecondSummandContainer);
                }
а надо чтоб было

Also create a Sum() function that calculates the sum between two iterators. The function then uses the template argument for the iterator type and accepts two iterators, the start and end iterator

ща перевод найду он где то вверху был

Добавлено через 1 минуту
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Уроки литературного перевода
Используя итераторы, мы можем перемещаться по контейнеру STL, ничего не зная о самом контейнере. В этом упражнении вам предлагается реализовать функцию, вычисляющую сумму элементов типа double, хранимых в контейнере.
  • Создайте шаблонную функцию Sum(), которая принимает шаблонный аргумент типа T и возвращает double. Этот аргумент — это контейнер.
  • В функции получите итератор (T::const_iterator), указывающий на конец контейнера. Затем пройдитесь в цикле по контейнеру и сложите значения его элементов. Наконец, верните из функции сумму.
  • В главной программе вызовите Sum() для контейнера, отличающегося от применённого в предыдущем упражнении.
Данная функция Sum() вычисляет сумму всего контейнера. Также реализуйте Sum(), которая бы вычисляла сумму элементов между двумя итераторами. Шаблонный тип функции будет типом двух принимаемых итераторов, указывающих на начало и конец суммируемого региона.
вот перевод литературный ))) спасибо товарищу

Также реализуйте Sum(), которая бы вычисляла сумму элементов между двумя итераторами. Шаблонный тип функции будет типом двух принимаемых итераторов, указывающих на начало и конец суммируемого региона
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
09.08.2012, 21:31 16
Как вариант.
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
#include <iostream>
#include <vector>
#include <map>
 
template<typename T>
T get_el(const T& value)
{
    return value;
}
 
template<typename T, typename T2>
T2 get_el(const std::pair<const T, T2>& value)
{
    return value.second;
}
 
template<typename Container>
double sum(const Container& cnt)
{
   typedef typename Container::const_iterator c_iter;
   double sum = 0;
   for (c_iter i = cnt.begin();
        i != cnt.end();
        ++i)
   {
      sum += get_el(*i);
   }
   return sum;
}
 
template<typename Iterator>
double sum(Iterator first, Iterator last)
{
    double sum = 0;
    for (; first != last; ++first)
    {
        sum += get_el(*first);
    }
    return sum;
}
 
int main()
{
   double array[] = {1, 2};
   std::vector<double> v(array, array + sizeof(array) / sizeof(*array));
   std::cout << sum(v) << std::endl;
   std::pair<int, double> map[] = 
   {
     std::make_pair(1, 1.0),
     std::make_pair(2, 2.0)
   };
   std::map<int, double> m(map, map + sizeof(map) / sizeof(*map));
   std::cout << sum(m) << std::endl;
   std::cout << "By iters " << sum(m.begin(), m.end()) << std::endl;
}
1
7 / 7 / 3
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
09.08.2012, 21:37  [ТС] 17
Цитата Сообщение от ForEveR Посмотреть сообщение
Как вариант.
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
#include <iostream>
#include <vector>
#include <map>
 
template<typename T>
T get_el(const T& value)
{
    return value;
}
 
template<typename T, typename T2>
T2 get_el(const std::pair<const T, T2>& value)
{
    return value.second;
}
 
template<typename Container>
double sum(const Container& cnt)
{
   typedef typename Container::const_iterator c_iter;
   double sum = 0;
   for (c_iter i = cnt.begin();
        i != cnt.end();
        ++i)
   {
      sum += get_el(*i);
   }
   return sum;
}
 
template<typename Iterator>
double sum(Iterator first, Iterator last)
{
    double sum = 0;
    for (; first != last; ++first)
    {
        sum += get_el(*first);
    }
    return sum;
}
 
int main()
{
   double array[] = {1, 2};
   std::vector<double> v(array, array + sizeof(array) / sizeof(*array));
   std::cout << sum(v) << std::endl;
   std::pair<int, double> map[] = 
   {
     std::make_pair(1, 1.0),
     std::make_pair(2, 2.0)
   };
   std::map<int, double> m(map, map + sizeof(map) / sizeof(*map));
   std::cout << sum(m) << std::endl;
   std::cout << "By iters " << sum(m.begin(), m.end()) << std::endl;
}
вообще высший пилотаж !!!!
СПАСИБО ОГРОМНОЕ
0
4773 / 2582 / 894
Регистрация: 29.11.2010
Сообщений: 5,590
10.08.2012, 19:08 18
Лучший ответ Сообщение было отмечено как решение

Решение

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

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
#include <iostream>
#include <string>
#include <stdexcept>
#include <utility>
#include <vector>
#include <map>
 
// предикат, общий для простых типов и для std::pair<K, V>
struct PredicateCommon {
  // обычно возвращает собственно значение
  template <class T>
  T operator()(const T &value) { return value; }
  // в случае класса std::pair возвращает поле second
  template <class K, class V>
  V operator()(const std::pair<K, V> &value) { return value.second; }
};
 
// бинарная операция суммирования, велосипед для std::sum
// можно заменить плюсом
struct BinaryOperationSum {
  template <class T>
  T operator()(const T &a, const T &b) { return a + b; }
};
 
// общая функция, похожая на std::accumulate
// принимает бинарную функцию и предикат для элементов контейнера
template <class InputIterator, class T,
  class BinaryOperation, class Predicate>
T accumulate(InputIterator first, InputIterator last, T initialValue,
  BinaryOperation binaryOperation, Predicate predicate) {
  while (first != last)
    // выполняет бинарную операцию надо всеми элементами с применением
    // предиката
    initialValue = binaryOperation(initialValue, predicate(*first++));
  return initialValue;
}
 
// частный случай accumulate -- суммирование с заранее заданным предикатом
template <class InputIterator, class T>
T sum(InputIterator first, InputIterator last, T initialValue) {
  return accumulate(first, last, initialValue, BinaryOperationSum(),
    PredicateCommon());
}
 
// частный случай sum -- суммирование всех элементов контейнера с заранее заданным предикатом
template <class Container, class T>
T sum(const Container &container, T initialValue) {
  return sum(container.begin(), container.end(), initialValue);
}
 
int main(int argc, char **argv) {
  std::map<int, double> d;
  d[0] = 0.72;
  d[1] = 0.12;
  d[2] = 1.22;
  std::cout << sum(d, 0.0d) << std::endl;
  std::cout << intToString(100, 16) << std::endl;
  return 0;
};
4
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.08.2012, 20:20 19
lemegeton, извините за оффтоп, но что за intToString(100, 16)?
1
4773 / 2582 / 894
Регистрация: 29.11.2010
Сообщений: 5,590
11.08.2012, 00:49 20
Цитата Сообщение от talis Посмотреть сообщение
lemegeton, извините за оффтоп, но что за intToString(100, 16)?
Пардон, это из другой оперы. Случайно закопипастилось.
1
11.08.2012, 00:49
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.08.2012, 00:49
Помогаю со студенческими работами здесь

Программа аварийно завершается с ошибкой "map/set iterators are incompatible"
Добрый день! Проблема такая: в s1 и s2 рандомно добавляю числа, хочу найти объединение этих...

vector(выскакивает ошибка "vector iterators incompatible")
Доброго времени суток! имеется следующий код: // obr.cpp : Defines the entry point for the...

STL
Данная программа делает следующее 1. Создать объект-контейнер в соответствии с вариантом задания и...

STL
Доброго времени суток! Возникли трудности с пониманием задачи и принципа работы программы....

STL
Всем привет :) Задача следующая - Нужно считать из файла строки, запихнуть их в стек и вывести на...

STL
Задача: сторонами треугольников и прямоугольников являются цветные (red, green, blue)...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru