this dir | view | cards | source | edit | dark top

cviceni

cviceni

cvičení

zápočtové testy

zápočtové programy

můžeme používat překladače ve Visual Studiu

ve VS Code

dá se nainstalovat microsoftí překladač nebo gcc nebo clang ve verzi pro windows

na Windows bychom měli programy psát tak, aby fungovaly i na Linuxu

na grafické rozhraní knihovna Qt

budou po nás chtít překlad bez warningů

je dobré z programů vracet nulu

argv

vector

stringy

int main(int argc, char** argv) {
    std::vector<std::string> arg(argv, argv + argc);
    
    for (int i = 0; i < argc; ++i) {
        // tohle nebude fungovat, protože arg[i] neopovídá typu %s
        std::printf("%d: %s\n", i, arg[i]);
    }
    
    return 0;
}

aliasy typů pomocí using, používá se předpona t_

using t_arg = std::vector<std::string>;

for (auto&& x : parg)


třída std::ifstream … vstupní souborový stream

debug režim

starší funkce ze standardní knihovny nevypouštějí výjimky

příznak eof se nastaví až po tom, co se pokusíme přečíst data za koncem souboru

takže po každém čtení kontrolujeme fail, pokud to zfailovalo a nastavil se příznak eof, je to v pohodě – jsme na konci souboru

zajímavé věci, které můžeme použít


časté chyby a poznámky

vyhodnocování výrazů

poznámky

rozdělit projekt parseru do více „modulů“ (postaru)

strom výrazu

OOP

alternativní úloha

std::numeric_limits<T>

std::plus a podobné objekty

template<typename OP>
class binary : public abstop {
    public:
        binary(.... l, .... r) : left(std::move(l)), right(std::move(r)) {}
        virtual int eval() const override {
            return f(left->eval(), right->eval())
        }
    private:
        ..... left, right, OP f;
}

taky by tam mohlo být třeba return OP()(left->eval(), right->eval());

nebo by první závorky mohly být složené

jak udělat genericky i typ, co vrací eval?

jak to udělat, abychom nemuseli mít int v typech uvedený dvakrát (jednou pro eval, jednou v rámci plus)?

// chceme použít
binary<plus<int>>
// uvnitř bude
using my_type = typename OP::result_type; // nefunguje v C++20
// nebo
// chceme použít
binary<int, plus>
// to se dělá takhle
template<typename my_type, template<typename> typename GOP>
class binary : public abstrop<my_type> {
    using OP = GOP<my_type>;
}

naše mainy mají vracet nulu, jinak s tím recodex bude mít problém


je dobré ty řádky udělat tak, aby se daly iterovat třeba pomocí dvojtečkového for cyklu

matice by měla být šablona

ale zatím asi psát bez šablon

lze implementovat pomocí vektoru vektorů

lze implementovat pomocí jednoho vektoru

class row_iterator {
    public:
        row_iterator &operator ++() {
            // něco
            return *this;
        }
        // tohle je prefixový ++
        // kdybychom chtěli postfixový, bylo by to s jedním intovým parametrem
        // (žádný intový argument se nepředává)
        // a musíme vracet hodnotou
        row_iterator operator ++(int) {
            row_iterator tmp = *this;
            ++*this;
            return tmp;
        }
        row_ref operator *() const { /* ... */ }
        // trikové řešení: do iterátoru zavřu row_ref
        // obvykle se z operátoru hvězdičky vrací T&
        
}
bool operator !=(const row_iterator& a, const row_iterator& b) { /* ... */ }
// můžeme implementovat spaceship operator

iterátory pro prvky řádku už můžou být přímo C pointery

C pointery mají vlastnosti iterátorů

co potřebujeme


zápočtový test

úloha

co když chytám do proměnné typu auto&& návratovou hodnotu funkce a funkce mi vrátí hodnotou?

každý kontejner má v sobě definovat typ iterator

každý iterátor má v sobě definovat typ reference

typename

když podporujeme hvězdičku, měli bychom podporovat šipku


typické chyby

poznámky

map<string, size_t> m;
if (m.exists(ident)) {
    id = m[ident];
    // neefektivní řešení, v mapě vyhledávám dvakrát
} else {
    m[ident] = id = m.size();
}

lepší je použít m.find, to vrátí iterátor it

jak to udělat správně?

id = m.size();
auto [it, b] = m.emplace(ident, id);
if (!b) {
    id = it->second;
}
// b je true, pokud tam ten prvek ještě nebyl
// když se emplace nepovedl, tak je b false a iterátor míří na překážející prvek

další varianta: try_emplace

výhodnější – nevytváří objekt, dokud není jasné, že tam půjde vložit

úloha index_map


naše řešení můžeme vylepšovat až do okamžiku před testem

deadline je měkký – můžeme submitovat i potom

připomenutí

příklad: telefonní seznam

orientovaný graf

Hurá, máš hotovo! 🎉
Pokud ti moje kartičky pomohly, můžeš mi koupit pivo.