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

Kód: [Vybrat]
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

Kód: [Vybrat]
|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:
Kód: [Vybrat]
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á.

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:
Kód: [Vybrat]
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,

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

presto me vsak jeste neco nehraje

Kód: [Vybrat]
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):
Kód: [Vybrat]
#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:

Kód: [Vybrat]
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++  :)

Kód: [Vybrat]
#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++:
Kód: [Vybrat]
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:
Kód: [Vybrat]
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.
Kód: [Vybrat]
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'|

Kód: [Vybrat]
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 »
bohuzel opet error:

Kód: [Vybrat]
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 »
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:
Kód: [Vybrat]
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