LINUX.ORG.RU

functional object


0

1

всех приветствую в исходниках STL функтор передается по значению

template<class _InIt,
	class _Fn1> inline
	_Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
	{	// perform function for each element
	for (; _ChkFirst != _ChkLast; ++_ChkFirst)
		_Func(*_ChkFirst);
	return (_Func);
	}

можно исправить

_Func(*_ChkFirst); на (*_Func)(*_ChkFirst);
перегрузить еще одну операцию в функторе
class type{
	... buff[VERY_BIG_SIZE];
public:
	type& operator*(){return *this;}
	void operator()(... e){}
};
и можно передавать и по значению и по указателю эффективней ?

template<class _InIt,
	class _Fn1> inline
	_Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
	{	// perform function for each element
	for (; _ChkFirst != _ChkLast; ++_ChkFirst)
		(*_Func)(*_ChkFirst);
	return (_Func);
	}

например

type obj; for_each(..., ..., &obj);
          for_each(..., ...., obj);


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

osox
() автор топика
Ответ на: комментарий от osox

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

читай внимательно

jtootf ★★★★★
()
Ответ на: комментарий от osox

>компилятор эффективней код начинает генерить в релизе с включенной оптимизацией разница есть не копируется в стек каждый раз копия объекта интересно почему не сделали по указателю изначально главное при этом остается возможность передачи по значению

Ты в жизни тоже так разговариваешь?

anonymous
()
Ответ на: комментарий от osox

сначала буксуй в пятый класс, русскому языку учиться

быдлокодеры, ять вашу

doctorch
()
Ответ на: комментарий от anonymous

он в жизни мычит и бьётся головой о стену ритмично

doctorch
()

Сделай бенчмарки, посмотрим.

yoghurt ★★★★★
()

вопрос интересный — только вместо указателя надо передавать ссылку

вот какой он у меня:

template<typename _InputIterator, typename _Function>
    _Function
    for_each(_InputIterator __first, _InputIterator __last, _Function  __f)
    {
      // concept requirements
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
      __glibcxx_requires_valid_range(__first, __last);
      for (; __first != __last; ++__first)
        __f(*__first);
      return __f;
    }
я думаю так не сделали потому, что одно копирование по сравнению с целым циклом это считай ничто, и компилятор скорее всего его сумеет соптимизировать; а результат, полученный в функторе, возвращается через return, и опять ссылка не нужна

действительно нужно замерить скорость; предлагаю

array int[M*N];
for(int i=0; i<M*N; i++)
  array[i][0]=i;

SumFunctor s;
for(int i=0; i<M*N; i+=N) 
  s=for_each(array[i], array[i+N], s);

g++ test.cxx -DM=1000000 -DN=1

сравнить с

g++ test.cxx -DM=1 -DN=1000000

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

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

	std::for_each(v.begin(), v.end(), &vg);
00401D10 8D 45 D8         lea         eax,[v] 
00401D13 50               push        eax  
00401D14 FF 75 E8         push        dword ptr [ebp-18h] 
00401D17 8D 4D F8         lea         ecx,[ebp-8] 
00401D1A E8 32 F7 FF FF   call        std::_Vector_const_iterator<int,std::allocator<int> >::_Vector_const_iterator<int,std::allocator<int> > (401451h) 
00401D1F 8D 45 D8         lea         eax,[v] 
00401D22 50               push        eax  
00401D23 FF 75 E4         push        dword ptr [ebp-1Ch] 
00401D26 8D 4D F0         lea         ecx,[ebp-10h] 
00401D29 E8 23 F7 FF FF   call        std::_Vector_const_iterator<int,std::allocator<int> >::_Vector_const_iterator<int,std::allocator<int> > (401451h) 
00401D2E 68 E0 FF 40 00   push        offset vg (40FFE0h) 
00401D33 FF 75 FC         push        dword ptr [ebp-4] 
00401D36 FF 75 F8         push        dword ptr [ebp-8] 
00401D39 FF 75 F4         push        dword ptr [ebp-0Ch] 
00401D3C FF 75 F0         push        dword ptr [ebp-10h] 
00401D3F E8 50 F9 FF FF   call        std::for_each<std::_Vector_iterator<int,std::allocator<int> >,type *> (401694h) 
00401D44 83 C4 14         add         esp,14h 
///////////////////////////////////////////////////////////////////
а тут копируется все тело функтора в стек потом происходит вызов причем даже на самом высоком уровне оптимизации все равно создается копия и обычный вызов происходит
	std::for_each(v.begin(), v.end(), vg);
00401D1D 8D 45 D8         lea         eax,[v] 
00401D20 50               push        eax  
00401D21 FF 75 E8         push        dword ptr [ebp-18h] 
00401D24 8D 4D F8         lea         ecx,[ebp-8] 
00401D27 E8 10 F7 FF FF   call        std::_Vector_const_iterator<int,std::allocator<int> >::_Vector_const_iterator<int,std::allocator<int> > (40143Ch) 
00401D2C 8D 45 D8         lea         eax,[v] 
00401D2F 50               push        eax  
00401D30 FF 75 E4         push        dword ptr [ebp-1Ch] 
00401D33 8D 4D F0         lea         ecx,[ebp-10h] 
00401D36 E8 01 F7 FF FF   call        std::_Vector_const_iterator<int,std::allocator<int> >::_Vector_const_iterator<int,std::allocator<int> > (40143Ch) 
00401D3B B8 5C 65 03 00   mov         eax,3655Ch 
00401D40 E8 8B 0E 00 00   call        _chkstk (402BD0h) 
00401D45 8B FC            mov         edi,esp 
00401D47 FF 75 FC         push        dword ptr [ebp-4] 
00401D4A B9 56 D9 00 00   mov         ecx,0D956h 
00401D4F FF 75 F8         push        dword ptr [ebp-8] 
00401D52 BE 00 00 41 00   mov         esi,offset vg (410000h) 
00401D57 FF 75 F4         push        dword ptr [ebp-0Ch] 
00401D5A F3 A5            rep movs    dword ptr es:[edi],dword ptr [esi] 
00401D5C FF 75 F0         push        dword ptr [ebp-10h] 
00401D5F 66 A5            movs        word ptr es:[edi],word ptr [esi] 
00401D61 8D 85 7D 9A FC FF lea         eax,[ebp-36583h] 
00401D67 50               push        eax  
00401D68 A4               movs        byte ptr es:[edi],byte ptr [esi] 
00401D69 E8 11 F9 FF FF   call        std::for_each<std::_Vector_iterator<int,std::allocator<int> >,type> (40167Fh) 
00401D6E 81 C4 70 65 03 00 add         esp,36570h 
/////////////////////////////////////////////////////////////////////////////

osox
() автор топика
Ответ на: комментарий от www_linux_org_ru

надо было так сделать

type obj;
for_each<..., type&>(..., ..., obj);
и передается ссылка а вот если явно не указать тип то даже подставив ссылку передается по значению а не по ссылке
type obj;
type &r = obj;
for_each(..., ..., r);

osox
() автор топика
Ответ на: комментарий от www_linux_org_ru

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

osox
() автор топика
Ответ на: комментарий от www_linux_org_ru

вопрос интересный — только вместо указателя надо передавать ссылку

на временный объект, например?

jtootf ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.