Форум программистов, компьютерный форум CyberForum.ru

STL Iterators - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.92
Leeto
 Аватар для Leeto
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
07.08.2012, 19:13     STL Iterators #1
Допустим есть проект

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 аргумента а не один для как для листа и вектора ) подскажите плиз )
Заранее спасибо !
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.08.2012, 19:13     STL Iterators
Посмотрите здесь:

C++ STL
STL C++
iterators & file C++
C++ STL
[C++]Problems with iterators C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
07.08.2012, 19:42     STL Iterators #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/d3c4c1...a816c36c597b22

Или сделать функцию от двух итераторов, но все равно нужно будет некое подобие перегрузок функции get_el.
lemegeton
 Аватар для lemegeton
2910 / 1339 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
07.08.2012, 22:39     STL Iterators #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;
}
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
07.08.2012, 23:56     STL Iterators #4
lemegeton, Ну accumulate-то да конечно.
Leeto
 Аватар для Leeto
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
09.08.2012, 18:58  [ТС]     STL Iterators #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  
Leeto
 Аватар для Leeto
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
09.08.2012, 19:15  [ТС]     STL Iterators #6
Так ладно попробую разобраться
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
09.08.2012, 19:45     STL Iterators #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;
}
Так? :-)
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
09.08.2012, 19:50     STL Iterators #8
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Уроки литературного перевода
Используя итераторы, мы можем перемещаться по контейнеру STL, ничего не зная о самом контейнере. В этом упражнении вам предлагается реализовать функцию, вычисляющую сумму элементов типа double, хранимых в контейнере.
  • Создайте шаблонную функцию Sum(), которая принимает шаблонный аргумент типа T и возвращает double. Этот аргумент — это контейнер.
  • В функции получите итератор (T::const_iterator), указывающий на конец контейнера. Затем пройдитесь в цикле по контейнеру и сложите значения его элементов. Наконец, верните из функции сумму.
  • В главной программе вызовите Sum() для контейнера, отличающегося от применённого в предыдущем упражнении.
Данная функция Sum() вычисляет сумму всего контейнера. Также реализуйте Sum(), которая бы вычисляла сумму элементов между двумя итераторами. Шаблонный тип функции будет типом двух принимаемых итераторов, указывающих на начало и конец суммируемого региона.
Leeto
 Аватар для Leeto
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
09.08.2012, 20:11  [ТС]     STL Iterators #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::allocator<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 не работает
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
09.08.2012, 20:29     STL Iterators #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;
}
Leeto
 Аватар для Leeto
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
09.08.2012, 20:43  [ТС]     STL Iterators #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;
            }
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
09.08.2012, 20:57     STL Iterators #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/c43f09...1e59446df9bf30
Leeto
 Аватар для Leeto
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
09.08.2012, 21:06  [ТС]     STL Iterators #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/c43f09...1e59446df9bf30

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 ==========



у меня одного этот код не компелируется ?
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
09.08.2012, 21:17     STL Iterators #14
Leeto, В VS тоже не работает... Ща придумаю что-нибудь.
Leeto
 Аватар для Leeto
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
09.08.2012, 21:26  [ТС]     STL Iterators #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(), которая бы вычисляла сумму элементов между двумя итераторами. Шаблонный тип функции будет типом двух принимаемых итераторов, указывающих на начало и конец суммируемого региона
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
09.08.2012, 21:31     STL Iterators #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;
}
Leeto
 Аватар для Leeto
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
09.08.2012, 21:37  [ТС]     STL Iterators #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;
}
вообще высший пилотаж !!!!
СПАСИБО ОГРОМНОЕ
lemegeton
 Аватар для lemegeton
2910 / 1339 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
10.08.2012, 19:08     STL Iterators #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;
};
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.08.2012, 20:20     STL Iterators #19
lemegeton, извините за оффтоп, но что за intToString(100, 16)?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.08.2012, 00:49     STL Iterators
Еще ссылки по теме:

Оибка vector iterators incompatible ? C++
vector(выскакивает ошибка "vector iterators incompatible") C++
C++ Map/set iterators are incompatible

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

Или воспользуйтесь поиском по форуму:
lemegeton
 Аватар для lemegeton
2910 / 1339 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
11.08.2012, 00:49     STL Iterators #20
Цитата Сообщение от talis Посмотреть сообщение
lemegeton, извините за оффтоп, но что за intToString(100, 16)?
Пардон, это из другой оперы. Случайно закопипастилось.
Yandex
Объявления
11.08.2012, 00:49     STL Iterators
Ответ Создать тему
Опции темы

Текущее время: 02:36. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru