Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Typ iterowania dla pętli for - size_t, int, unsigned int

Ostatnio zmodyfikowano 2019-01-09 13:49
Autor Wiadomość
Anim
Temat założony przez niniejszego użytkownika
Typ iterowania dla pętli for - size_t, int, unsigned int
» 2019-01-09 09:35:07
Kiedyś nie zwracałem na to uwagi, ale od pewnego momentu mam w każdym swoim kodzie ostrzeżenia o tym, że konwertuję nieodpowiedni typ dla wektora, bądź zmiennej w pętli. Chodzi oczywiście o sytuację, jak poniżej:


C/C++
std::vector < int > A;
/*
        Tutaj dodajemy dane do wektora
*/

for( int i = 0; i < A.size(); ++i ) //(ostrzeżenie: implicit conversion loses integer precision: 'size_t' (aka 'unsigned long') to 'int')
{
    std::cout << A[ i ] << std::endl;
}

Ostrzeżenie jest oczywiście przy zakresie dla pętli for. Mogę zmienić int na size_t, ale wtedy w innej sytuacji, nie mogę wykorzystać zmiennej zakresowej "i" w innym przypadku, aby nie narazić się na to samo ostrzeżenie, tylko w innym miejscu, czyli:


C/C++
std::vector < int > A;
/*
        Tutaj dodajemy dane do wektora
*/

for( size_t i = 0; i < A.size(); ++i )
{
    std::cout << A[ i ] << std::endl;
   
   
    //tutaj przykładowe przypisanie, gdzie pojawia się ostrzeżenie (ostrzeżenie: implicit conversion loses integer precision: 'size_t' (aka 'unsigned long') to 'int'):
    int tmp = i;
}

Jak poprawnie iterować po wektorach? czy powinno się zawsze używać iteratora? Bądź pętli zakresowej? Jest jakaś "ogólna zasada"? A może nie powinno używać się w pętli iteracyjnej i<wektor.size()?
P-173468
jankowalski25
» 2019-01-09 13:27:17
Dopóki działasz na liczbach prawidłowych dla obu typów, wystarczy po prostu rzutować:
C/C++
static_cast < int >( zmienna_size_t );
static_cast < std::size_t >( zmienna_int );
Gorzej, jeśli masz na przykład
- 1
, w takim przypadku lepiej jawnie napisać, co ma się stać (na przykład przypisując wartość
std::numeric_limits < std::size_t >::max()
). Ogólnie rzecz biorąc do iterowania po wektorze wystarczy używać
std::size_t
 (chyba że koniecznie chcesz mieć typ związany z tym wektorem, wtedy oczywiście
std::vector < int >::size_type
, ale to już chyba lekka przesada, zresztą niemal zawsze[1] to będzie równoznaczne z użyciem
std::size_t
).

[1] „Niemal zawsze”, ponieważ jest to zależne od implementacji. Może się zdarzyć tak, że ten typ będzie zdefiniowany jako
typedef Allocator::size_type size_type;
, co w przypadku własnych alokatorów może oznaczać inny typ (mogący nie pozwalać na niejawną konwersję do
std::size_t
).
P-173470
Anim
Temat założony przez niniejszego użytkownika
» 2019-01-09 13:46:47
Dziękuję za wyjaśnienie :)
P-173472
jankowalski25
» 2019-01-09 13:49:28
A może nie powinno używać się w pętli iteracyjnej i<wektor.size()?
Jeśli nie potrzebujesz znać numeru obecnie przetwarzanego elementu, to pętla foreach lepiej tu pasuje.
P-173473
« 1 »
  Strona 1 z 1