STL Vector ukazatelu na instance tridy a sort c++

Jenda

STL Vector ukazatelu na instance tridy a sort c++
« kdy: 15. 03. 2012, 23:55:49 »
Ahoj, snazim se setridit vector s ukazateli, mam nasledujici kod, ktery jsem pokoumal poruznu na forech


class TZaznam
    {
        public:
        char Zanr;
        char Typ;
        char Novinka;
    };

class TPlaylist
   {
    public:
        vector <TZaznam*>PoleZaznamu;
        bool  PorovnejRetezec(  const TZaznam *prvni,  const TZaznam *druhy );

};

void TPlaylist::SetridPoleZaznamu()
    {

        sort( PoleZaznamu.begin(), PoleZaznamu.end(), PorovnejRetezec);
    }


Bohuzel vsak dostavam nasledujici hlaseni od prekladace

|32|error: no matching function for call to 'sort(__gnu_cxx::__normal_iterator<TZaznam**, std::vector<TZaznam*, std::allocator<TZaznam*> > >, __gnu_cxx::__normal_iterator<TZaznam**, std::vector<TZaznam*, std::allocator<TZaznam*> > >, <unresolved overloaded function type>)'|

Danemu hlaseni bohuzel vubec nerozumim a ani strejda google mi nedal odpoved. Rad bych tedy poprosil nekoho o radu.

Predem moc dekuji


JohnyS

Re:STL Vector ukazatelu na instance tridy a sort c++
« Odpověď #1 kdy: 16. 03. 2012, 00:18:44 »
Porovnavacia funkcia ocakava pointer na typ triedenych prvkov, kedze prvky vectoru su pointre na  TZaznam, porovnavacia funkcia ocakava pointer na pointer na TZaznam a teda:
bool  PorovnejRetezec(  const TZaznam **prvni,  const TZaznam **druhy );
o hviezdicku viac :)

Sten

Re:STL Vector ukazatelu na instance tridy a sort c++
« Odpověď #2 kdy: 16. 03. 2012, 00:20:32 »
Ta hláška říká jednoduše to, že žádná metoda std::sort pro dané parametry neexistuje. Třetí parametr pro std::sort totiž musí být funktor, zatímco vy tam máte metodu, která dokonce ani není statická.

Citace od: JohnyS kdy 16. 03. 2012, 00:18:44
Porovnavacia funkcia ocakava pointer na typ triedenych prvkov, kedze prvky vectoru su pointre na  TZaznam, porovnavacia funkcia ocakava pointer na pointer na TZaznam a teda:
bool  PorovnejRetezec(  const TZaznam **prvni,  const TZaznam **druhy );
o hviezdicku viac :)

Porovnávací funktor dostává reference na porovnávané prvky.

Jenda

Re:STL Vector ukazatelu na instance tridy a sort c++
« Odpověď #3 kdy: 16. 03. 2012, 09:41:11 »
dekuji za promtni odpovedi,

metodu jsem tedy uvedl jako statickou a pridal ukazatel na ukazatel,

Citacestatic bool  PorovnejRetezec(  const TZaznam **prvni,  const TZaznam **druhy ){return true;}

presto me vsak jeste neco nehraje

cannot convert 'TZaznam* const' to 'const TZaznam**' in argument passing

nekde jsem jeste videl pouziti "ptr_fun()" ale to si nejsem uplne jisty co by to melo delat. Tuzim ze asi neco jako ukazatel na funkci.

Re:STL Vector ukazatelu na instance tridy a sort c++
« Odpověď #4 kdy: 16. 03. 2012, 10:12:16 »
Co treba takhle (viz Sten):

#include <vector>
#include <algorithm>

class TZaznam
{
public:
  char Zanr;
  char Typ;
  char Novinka;
};

using namespace std;

class TPlaylist
{

  struct {
    bool operator()(const TZaznam *prvni,  const TZaznam *druhy );
  } PorovnejZaznam;

public:
  vector <TZaznam*>PoleZaznamu;

  void SetridPoleZaznamu()
  {   
    sort( PoleZaznamu.begin(), PoleZaznamu.end(), PorovnejZaznam);
  }
};



Jenda

Re:STL Vector ukazatelu na instance tridy a sort c++
« Odpověď #5 kdy: 16. 03. 2012, 12:06:20 »
bohuzel opet error:

error: no matching function for call to 'sort(__gnu_cxx::__normal_iterator<TZaznam**, std::vector<TZaznam*, std::allocator<TZaznam*> > >, __gnu_cxx::__normal_iterator<TZaznam**, std::vector<TZaznam*, std::allocator<TZaznam*> > >, TPlaylist::<anonymous struct>&)'|

Re:STL Vector ukazatelu na instance tridy a sort c++
« Odpověď #6 kdy: 16. 03. 2012, 13:06:58 »
Ono zrejme take zalezi na verzi prekladace. Ja to zkusil s g++ verze 4.6. S nim je to v poradku. Prekladac intel composer xe (sp1, 8.273) tj. icpc to neprelozi a dava stejnou chybovou hlasku jako u Vas. Staci mu ale vnutit novy standard pomoci -std=c++0x a pak to jde.

Nasledujici priklad (doplneni predchoziho) je vyzkousen v linuxu s g++ a s icpc -std=c++0x. Jaky prekladac pouzivate Vy?

P.S. miluji prenositelnost programu C/C++  :)


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

class TZaznam
{
public:
  char Zanr;
  char Typ;
  char Novinka;
};

using namespace std;

class TPlaylist
{

  struct {
    bool operator()(const TZaznam *prvni,  const TZaznam *druhy ) {
      return prvni->Zanr < druhy->Zanr;
    };
  } PorovnejZaznam;

public:
  vector <TZaznam*>PoleZaznamu;

  void SetridPoleZaznamu()
  {   
    std::sort( PoleZaznamu.begin(), PoleZaznamu.end(), PorovnejZaznam);
  }
};


int main() {

  TPlaylist pl;
  TZaznam *z;

  z = new TZaznam;
  z-> Zanr = 'r';
  pl.PoleZaznamu.push_back(z);

  z = new TZaznam;
  z-> Zanr = 'p';
  pl.PoleZaznamu.push_back(z);

  z = new TZaznam;
  z-> Zanr = 's';
  pl.PoleZaznamu.push_back(z);

  cout << "Puvodni playlist:" << endl;
  for (int i = 0; i< pl.PoleZaznamu.size(); i++)
    cout << pl.PoleZaznamu[i]->Zanr << " ";
  cout << endl;

  // Setridim
  pl.SetridPoleZaznamu();

  cout << "Setrideny playlist:" << endl;
  for (int i = 0; i< pl.PoleZaznamu.size(); i++)
    cout << pl.PoleZaznamu[i]->Zanr << " ";
  cout << endl;

  return 0;
}


S g++:

petanque:~/Vyuka/PIA/STL$ g++ sort.cpp
petanque:~/Vyuka/PIA/STL$ ./a.out
Puvodni playlist:
r p s
Setrideny playlist:
p r s


s intelem:

petanque:~/Vyuka/PIA/STL$ icpc -std=c++0x sort.cpp
Warning #2928: the __GXX_EXPERIMENTAL_CXX0X__ macro is disabled when using GNU version 4.6 with the c++0x option

petanque:~/Vyuka/PIA/STL$ ./a.out
Puvodni playlist:
r p s
Setrideny playlist:
p r s

Jenda

Re:STL Vector ukazatelu na instance tridy a sort c++
« Odpověď #7 kdy: 16. 03. 2012, 20:09:04 »
Dekuji za pomoc , uz to funguje, stacilo nainstalovat novou verzi mingw. Prekladal jsem to na verzi, ktera se automaticky nainstalovala s codeblocs tusim 4.5

Jenda

Re:STL Vector ukazatelu na instance tridy a sort c++
« Odpověď #8 kdy: 17. 03. 2012, 07:06:34 »
Tak jeste se vyskytl jeden problem a to s iteratory, ale to bude nejspis moje chyba sintaxe. Snazim se setridit jiz jenom cast toho pole pointeru na objekty.

c:\programovani\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\bits\stl_iterator_base_types.h|166|error: no type named 'iterator_category' in 'class TZaznam'|



void TPlaylist::SetridPoleZaznamu()
    {
    stable_sort( PoleZaznamu.begin(), PoleZaznamu.end(), PorovnejAlbum); //tento radek funguje bezchybne
    stable_sort( PoleZaznamu.begin(), PoleZaznamu.end(), PorovnejZanr); //tento radek take funguje

    vector<TZaznam*>::iterator Aktualni,Predni,Zadni; //vytvarim iteratory

    Predni=PoleZaznamu.begin();

    if (PoleZaznamu.size()>1)
        {
        for ( Aktualni=Predni ; Aktualni < PoleZaznamu.end()-1; Aktualni++ )
            {
            Zadni=Aktualni;
            if (((**Predni).NazevAlba).compare((**Zadni++).NazevAlba) != 0) //porovnani se zda byt take v poradku
                {
                stable_sort(**Predni, **Aktualni, PorovnejPisen);  //zde se generuje chyba
                Predni=Aktualni++;
                }     
            }

        }
    }



Budu velice vdecen za jakykoliv napad co stim.



Waseihou

Re:STL Vector ukazatelu na instance tridy a sort c++
« Odpověď #9 kdy: 19. 03. 2012, 13:00:21 »
for ( Aktualni=PoleZaznamu.begin() ; Aktualni != PoleZaznamu.end(); ++Aktualni)

end() vrací vždy jeden prvek za posledním takže stačí porovnávat na != a nemusí být relace <

pro inkrementaci iterátoru používej preincrement ++iter namísto iter++ pro maximální přenositelnost, ne každý objekt implementuje postincrement operátor, takže některé části kódu rozepiš na dva řáky

Predni = Aktualni;
++Aktualni;

sice to je méně kompaktní, ale až to bude někdo někdy krokovat v debuggeru, tak tě nebude proklínat

mrkni jak je udělané for_each
http://www.cplusplus.com/reference/algorithm/for_each/
pro inspiraci

demeter

Re:STL Vector ukazatelu na instance tridy a sort c++
« Odpověď #10 kdy: 19. 03. 2012, 16:58:34 »
Citace od: Jenda kdy 16. 03. 2012, 12:06:20
bohuzel opet error:

error: no matching function for call to 'sort(__gnu_cxx::__normal_iterator<TZaznam**, std::vector<TZaznam*, std::allocator<TZaznam*> > >, __gnu_cxx::__normal_iterator<TZaznam**, std::vector<TZaznam*, std::allocator<TZaznam*> > >, TPlaylist::<anonymous struct>&)'|


Problem je v tom, ze podle starsiho standardu C++ nelze pouzit "nepojmenovany" typ jako template argument.
Tj, "struct { ... }" jakozto typ funktoru PorovnejZaznam v template funkci std::sort().

Vyresis to napriklad jednoduse pojmenovanim typu funktoru:
   struct TPorovnejZaznam { ... } PorovnejZaznam;

Sten

Re:STL Vector ukazatelu na instance tridy a sort c++
« Odpověď #11 kdy: 19. 03. 2012, 17:45:25 »
Citace od: Waseihou kdy 19. 03. 2012, 13:00:21
for ( Aktualni=PoleZaznamu.begin() ; Aktualni != PoleZaznamu.end(); ++Aktualni)

end() vrací vždy jeden prvek za posledním takže stačí porovnávat na != a nemusí být relace <

pro inkrementaci iterátoru používej preincrement ++iter namísto iter++ pro maximální přenositelnost, ne každý objekt implementuje postincrement operátor, takže některé části kódu rozepiš na dva řáky

Predni = Aktualni;
++Aktualni;

Doporučil bych:
for ( ...::iterator Aktualni=PoleZaznamu.begin(), Konec=PoleZaznamu.end() ; Aktualni != Konec; ++Aktualni)
Volání metody .end() nemusí mít konstantní složitost a je zbytečné jej opakovat v každém kroku.

Jenda

Re:STL Vector ukazatelu na instance tridy a sort c++
« Odpověď #12 kdy: 19. 03. 2012, 20:45:08 »
Parada,  moc me to pomohlo. Velice vsem dekuji