Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: Jenda 15. 03. 2012, 23:55:49

Název: STL Vector ukazatelu na instance tridy a sort c++
Přispěvatel: Jenda 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
Název: Re:STL Vector ukazatelu na instance tridy a sort c++
Přispěvatel: JohnyS 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 :)
Název: Re:STL Vector ukazatelu na instance tridy a sort c++
Přispěvatel: Sten 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.
Název: Re:STL Vector ukazatelu na instance tridy a sort c++
Přispěvatel: Jenda 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.
Název: Re:STL Vector ukazatelu na instance tridy a sort c++
Přispěvatel: Jiri Furst 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);
  }
};
Název: Re:STL Vector ukazatelu na instance tridy a sort c++
Přispěvatel: Jenda 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>&)'|
Název: Re:STL Vector ukazatelu na instance tridy a sort c++
Přispěvatel: Jiri Furst 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
Název: Re:STL Vector ukazatelu na instance tridy a sort c++
Přispěvatel: Jenda 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
Název: Re:STL Vector ukazatelu na instance tridy a sort c++
Přispěvatel: Jenda 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.


Název: Re:STL Vector ukazatelu na instance tridy a sort c++
Přispěvatel: Waseihou 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
Název: Re:STL Vector ukazatelu na instance tridy a sort c++
Přispěvatel: demeter 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;
Název: Re:STL Vector ukazatelu na instance tridy a sort c++
Přispěvatel: Sten 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.
Název: Re:STL Vector ukazatelu na instance tridy a sort c++
Přispěvatel: Jenda 19. 03. 2012, 20:45:08
Parada,  moc me to pomohlo. Velice vsem dekuji