Diskuze: Nahrazení auto statickým typem, aneb co to je sakra za typ?
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.
Zobrazeno 6 zpráv z 6.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.
Ahoj, neviem či to máte povolené alebo nie, ale v C++14 môže byť aj návratový typ auto. A preto stačí v C++14 jednoducho:
const auto getIter(Pair *dummy)
{
return lower_bound(data.begin(), data.end(), dummy, [](const Pair *a, const Pair *b) {
return a->key < b->key;
});
}
Ak ale musíš používať C++11, musíš zistiť aký typ vracia funkcia lower bound.
Návratovy typ je ForwardIt, čo je typ prvého argumentu.
V tvojom prípade to je data.begin(), čo je iterátor triedy
std::vector.
Konkrétne je dátový typ iteratóra std::vector::iterator. Výsledná funkcia vyzerá takto:
const typename vector<Pair *>::iterator getIter(Pair *dummy)
{
return lower_bound(data.begin(), data.end(), dummy, [](const Pair *a, const Pair *b) {
return a->key < b->key;
});
}
(typename je tam preto, lebo typ Pair závisí na template
parametroch. Viac tu, proste to ber tak že to typename tam musí byť )
Alebo jednoduchšie riešenie je zistiť typ pomocou decltype a pomocou typedef deklarovať nový typ:
typedef decltype(data.begin()) typ_iteratora;
Jestli dobře vidím, tak atribut data, ze kterého přes auto bereš iterátory, má pro funkce begin a end definovány návratové typy
std::vector<Pair *>::iterator
std::vector<Pair *>::const_iterator
Viz třeba dokumentace k metodě begin (mrkni třeba na ten
příklad).
http://www.cplusplus.com/…ector/begin/
Máš pravdu, že pokud se třeba ve Visual Studiu podíváš na ty typy, je to šílenost, ale dokumentace existuje a je dobrá. Nemá smysl kvůli tomu na ten jazyk nadávat. Prostě u něj potřebuješ trochu více znalostí než u jiných.
Samozřejmě, kouzla s decltype budou lepší.
C'm on, teď jsem si z errorů kompilátoru vytáhl nějaký typ, co se mu
nepodařilo převést. Má 1365 znaků. To je přeci naprosto absurdní a
programátor by se v takovém bordelu neměl hrabat jen proto, že se někdo
neobtěžoval implementovat skutečnou generiku ... nebo rozumnou deklaraci
typů obecně
1365 znaků má ten typ, ne ta chyba.
programátor by se v takovém bordelu neměl hrabat jen proto, že se někdo neobtěžoval implementovat skutečnou generiku ... nebo rozumnou deklaraci typů obecně
Ta generika je implementována jinak než v ostatních jazycích. Jelikož se řeší čistě za překladu (v zásadě to jsou taková o hodně lepší preprocesorová makra), dovoluje dělat některé vylomeniny (například můžeš na generickém typu volat libovolné metody a překladač jejich existenci začne řešit až v případě, že deklaruješ instanci dané generiky... což mi v některých jazycích dost chybí, šetří to čas a řádky kódu, nesvazuje tě tolik dědičnost/polymorfismus).
Překladač ti do chybové hlášky píše název typu, jak si jej on vytvořil a odekoroval. Zrovna tvůj případ je, jestli jsem jej dobře pochopil, využití knihovní funkce, takže tam typ krásně najdeš v dokumentaci (možná bys i nějaký rozumný našel, pokud byses podíval na definici té funkce v příslušném hlavičkovém souboru... bohužel třeba MSVS ty typy u našeptávače překládá dost "do mrtě", takže jsou jejich názvy dlouhé a ne úplně přehledné (protože se prostě jde přes pojmenované typy, co to dá).
Proč jsi nepoužil ten const iterator? U STL kontejnerů je právě konvence, že iterátory se jmenují std::kontejner<typy>::(const_)iterator. S C++11 navíc přibylo řešení případu procházení celého kontejneru bez použití iterátoru
for (auto & prvek : kontejner) { . . . }
kde prvek bude typu odpovídajícímu referenci na postupně všechny prvky toho kontejneru (to referentítko je tam možná zbytečné). Takže obdoba podobně vypadajícíh cyklů v jiných jazycích.
Jinak nějakých 1365 znaků není nic extra . Před lety byla soutěž o
vygenerování nejdelší chybové hlášky v C++ a to byly gigabajty, ne-li
jejich desítky
.
Const iterátor jsem nakonec použil a jsem s tím kódem teď spokojen, jen mě štve, že se k tomu nemůžu dobrat z těch chybových hlášek. Já jsem si dokumentaci pročítal, říká, že vrací
iterator begin() noexcept;
const_iterator begin() const noexcept;
Ale nějak se nezmiňuje o tom, že iterator
je subclass od
vector
a mě to nenapadlo.
Jinak nějakých 1365 znaků není nic extra
. Před lety byla soutěž o vygenerování nejdelší chybové hlášky v C++ a to byly gigabajty, ne-li jejich desítky
.
Můj point přesně - žádný jiný jazyk (který znám ) ti něco takového nevyhodí a
člověk z toho může dokonce většinou poznat, co je vlastně špatně místo
těch hor z větší části bordelu, co vyhodí c++ kompilátory.
Zobrazeno 6 zpráv z 6.