For_each a metoda třídy – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

For_each a metoda třídy – C / C++ – Fórum – Programujte.comFor_each a metoda třídy – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené — příspěvek s řešením.
29. 8. 2013   #1
-
0
-

Ahoj,

chtěl jsem místo cyklu for použít for_each pro vykonání nějaké akce s každým prvkem ve vektoru.  Jak  ale zavolám metodu třídy na místě myfunction z ukázkového kódu?  http://www.cplusplus.com/reference/algorithm/for_each/

hu

Edit: používám C++ Builder 2010, nepodporuje C++11

Nahlásit jako SPAM
IP: 195.178.67.–
vitamin+8
Grafoman
29. 8. 2013   #2
-
+1
-
Zajímavé

#1 hlucheucho
Pouzi boost::bind. Alebo nieco taketo:

#include <iostream>
#include <vector>
#include <algorithm>

template<typename Return, typename This>
struct method_bind_t{
	typedef Return (This::*MethodPtr)() ;
	
	MethodPtr ptr;
	
	Return operator()(This& t)const{return (t.*ptr)();}
	
	method_bind_t& operator =(method_bind_t p){ptr = p.ptr;return *this;}
	method_bind_t& operator =(MethodPtr p){ptr = p;return *this;}
	method_bind_t():ptr(0){}
	method_bind_t(MethodPtr ptr):ptr(ptr){}
        method_bind_t(const method_bind_t& p):ptr(p.ptr){}
};

template<typename Return, typename This>
method_bind_t<Return, This> method_bind(Return (This::*ptr)()){ return method_bind_t<Return, This>(ptr);}
	
struct C{
	unsigned u;
	void fnc(){std::cout << "C::fnc: " << u << '\n';}
	
	C(unsigned u):u(u){}
};

int main(){	
	std::vector<C> vec;
	for(unsigned u = 0; u < 10; ++u)vec.push_back(C(u));
	
	std::for_each(vec.begin(), vec.end(), method_bind(&C::fnc) );
}
Nahlásit jako SPAM
IP: 95.105.152.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Řešení
Martin Kozibrátka0
Stálý člen
29. 8. 2013   #3
-
+1
-
Zajímavé
Vyřešeno Nejlepší odpověď

   

class ahoj
{
public: void  bla(int i){std::cout<<i;}


};

int _tmain(int argc, char* argv[])
{
	std::vector<int> myvector;
	ahoj k;
	myvector.push_back(10);
	myvector.push_back(20);
	myvector.push_back(30);

	std::cout << "myvector contains:";
	for_each (myvector.begin(), myvector.end(),bind1st (mem_fun(&ahoj::bla), &k));
	std::cout << '\n';

	return 0;
}
Nahlásit jako SPAM
IP: 188.120.221.–
Savana.cz - neomezený webhosting za pár kaček :)
KIIV
~ Moderátor
+43
God of flame
29. 8. 2013   #4
-
0
-

nebo vlastni funkcni objekt.. ikdyz to neni tak hezky jako pouzit bindy at uz z boostu nebo <functional> libky

neco jako:

#include <iostream>
#include <vector>
#include <algorithm>

class tvoje_trida {
  public:
    int polozka;
    tvoje_trida(int x): polozka(x) {}
    void metoda() { std::cout << polozka << std::endl; }
};

class funktor {
  public:
    void operator()(std::vector<tvoje_trida *>::value_type item)  { item->metoda(); }
};

int main() {
  std::vector<tvoje_trida *> vect;
  vect.push_back(new tvoje_trida(1));
  vect.push_back(new tvoje_trida(2));
  vect.push_back(new tvoje_trida(3));
  vect.push_back(new tvoje_trida(5));
  vect.push_back(new tvoje_trida(8));
  vect.push_back(new tvoje_trida(10));

  std::for_each(vect.begin(), vect.end(), funktor() );

  // jeste uvolnit vsechny alokovane objekty!!! 
  // dopln si sam :)

  return 0;
}
Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
29. 8. 2013   #5
-
0
-

#4 KIIV
vkládání třídy do kontejneru jsme zde před nějakou dobou řešili. Jestli si dobře pamatuji, je podporováno až od C++11, u C++ Builderu 2010 z tohoto důvodu nefungovalo. Nakonec jsem to vyřešil vkládáním ukazatelů do kontejneru. 

#2 vitamin
působivé, ale nedaří se mi to pochopit :(

hu

Nahlásit jako SPAM
IP: 195.178.67.–
KIIV
~ Moderátor
+43
God of flame
29. 8. 2013   #6
-
0
-

#5 hlucheucho
fungovat to bude pokud mas spravne copy konstruktory - upravim to na pointery v tom puvodnim prispevku

A problem s defaultnim copy konstruktorem je spis pri pouziti dynamicke pameti - musi se udelat kopie dat kazdyho pointeru na nove misto, protoze po pridani se vola nad puvodnim objektem destruktor a pokud by se jen zkopirovaly pointery (coz se defaultne dela), tak mas nahle neplatny data (muzou se kdykoliv prepsat necim dalsim)

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
vitamin+8
Grafoman
29. 8. 2013   #7
-
0
-

#5 hlucheucho

Funguje to tak ze trieda method_bind_t obsahuje pointer na metodu ktora ma navratovu hodnotu typu Return a this ma typ This. Dalej ma pretazeny operator () ktory prebera 1 parameter a pouzie ho ako this pre ulozeny pointer. Funkcia method_bind sluzi len na vytvorenie objektu method_bind_t.  Je to taka vseobecna verzia toho co napisal KIIV. 

Funguje to len pre metody ktore nepreberaju ziaden parameter (okrem this). Na viacej parametrov by uz trebalo variadic templaty ktore su az v c++11. 

Nahlásit jako SPAM
IP: 95.105.152.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Martin Kozibrátka0
Stálý člen
29. 8. 2013   #8
-
0
-

   Nebo použij statickou metodu třídy, to ale asi neni co uplne chceš


class MyClass
{
public:
  static void Test(int a) 
  {
    std::cout << a << std::endl;
  }
};

int _tmain(int argc, char* argv[])
{
	vector<int> myvector;
	myvector.push_back(5);
	myvector.push_back(6);
	for_each (myvector.begin(), myvector.end(),MyClass::Test);

	return 0;
}
Nahlásit jako SPAM
IP: 188.120.221.–
Savana.cz - neomezený webhosting za pár kaček :)
29. 8. 2013   #9
-
0
-

#6 KIIV
se mi to vlákno nedaří najít :(

hu

Nahlásit jako SPAM
IP: 195.178.67.–
KIIV
~ Moderátor
+43
God of flame
29. 8. 2013   #10
-
0
-

#9 hlucheucho
neni treba hledat... jak sem psal, upravil sem ten kod aby prijimal pointery misto reference na objekt...

kazdopadne to pak musis taky uvolnit...

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
vitamin+8
Grafoman
29. 8. 2013   #11
-
0
-

#5 hlucheucho
Preco vlastne nepouzies obycajny for?

Nahlásit jako SPAM
IP: 95.105.152.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
29. 8. 2013   #12
-
0
-

#11 vitamin
chtěl jsem se naučit něco nového a zjistit, jestli mi to něco přinese - snad lepší přehlednost kódu?

hu

Nahlásit jako SPAM
IP: 195.178.67.–
KIIV
~ Moderátor
+43
God of flame
29. 8. 2013   #13
-
0
-

#11 vitamin
tak ve foru se da udelat hromada chyb, todle je zaruceny ze to nejspis funguje. Vicemene je snaha, aby clocek programoval co nejmene veci, co uz je davno udelano a overeno tak aby se tam dalo nasekat co nejmene chyb

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
vitamin+8
Grafoman
29. 8. 2013   #14
-
0
-

#13 KIIV
Kebyze pouziva c++11 a lambda funkcie, boost::bind  alebo v generickom programovanie kde prebera celu funkciu/functor ako template parameter pripadne daku existujucu funkciu/functor (napr great<>, less<>, ...) tak nepoiem nic. Ale v tomto pripade je s tym viac prace ako uzitku.

Nahlásit jako SPAM
IP: 95.105.152.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
KIIV
~ Moderátor
+43
God of flame
29. 8. 2013   #15
-
0
-

jenze kdyz udelas treba:

for (int i = 1; i <= container.size(); i++) 

tak tam jsou hned 4 chyby:

* nevypise se prvni polozka

* zasahuje se mimo rozsah

* v kazdem kole se pocita size (coz u vetsiny standardnich kontejneru nevadi, ale strlen a podobny zverstva by se uz protahly)

* a post inkrementace (coz zase u intu nevadi, ale pro objekty uz to dela kopie a podobny optimalni veci, ktery se hned zase zahodi)

krom toho zasahu mimo rozsah se to vsechno muze hur hledat (a mimo rozsah taky kdyz se to nehlida)

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
vitamin+8
Grafoman
29. 8. 2013   #16
-
0
-

#15 KIIV
ja som mal na mysli skor toto:

for(Container_t::iterator i = container.begin(); i != container.end(); ++i)

Martin Kozibrátka dal aj tak asi nejlepsie riesenie, nevedel som ze tie funkcie su v c++03.

Nahlásit jako SPAM
IP: 95.105.152.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
29. 8. 2013   #17
-
0
-

http://programujte.com/forum/vlakno/24399-inicializace-pointeru-v-konstruktoru-tridy/

tady to bylo. Ve finále jsem objekty nechtěl kopírovat, předávám si objekt celou aplikací ukazatelem.

když se na zápis s for_each dívám, mám pochyby, zda je pro mne přínosem oproti cyklu for.

#16 vitamin
toto normálně používám

hu

Nahlásit jako SPAM
IP: 195.178.67.–
KIIV
~ Moderátor
+43
God of flame
29. 8. 2013   #18
-
0
-

#17 hlucheucho
aspon si poresil to, aby se objekty taky uvolnovaly? Tj. aby tam nebyl zadny memmory leak?

(ostatne i na to by se dalo udelat  RAII - nejaka mini trida uchovavajici jen pointer s pretizenym -> a * aby se to chovalo jako normalni pointer a hlavne destruktorem, aby po skonceni hodil delete - jen zase bacha pri kopirovani, aby se ten smejd neuvolnil hned... treba nastavit ten pointer jako mutable a maznout na NULL pri copy konstruktoru a assign operatoru + kontrola jestli se nekopiruje samo do sebe)

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
29. 8. 2013   #19
-
0
-

#18 KIIV
někde jsem tu kdysi psal zásadu: co jsem alokoval, to musím uvolnit. I v tomto případě se jí řídím. Že objekty obsahují dynamicky alokovaná pole, musím mít i odpovídající destruktory.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 37 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý