Použití přetíženého operátoru, vynutit přetypování operandu – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Použití přetíženého operátoru, vynutit přetypování operandu – C / C++ – Fórum – Programujte.comPoužití přetíženého operátoru, vynutit přetypování operandu – C / C++ – Fórum – Programujte.com

 

24. 3. 2021   #1
-
0
-

Ahoj,

mám třídu s přetíženými operátory. Bohužel se mi nedaří vyřešit problém s nejednoznačností operátoru v této situaci: 

MyClass op1, vysledek;
float op2;

vzsledek = op1 + op2;

Na základě chybového hlášení "operátor + je nejednoznačný" se domnívám, že se překladač nemůže rozhodnout mezi  float + float  a  MyClass + MyClass . Pokud explicitně přetypuji op1 na float, výpočet funguje. Operand op2 p5etzpovat na MyClass nejde. Nedaří se mi přijít na to, co v MyClass chybí.
Jak vynutit konverzi op2 na MyClass?

hu

Nahlásit jako SPAM
IP: 193.86.81.–
24. 3. 2021   #2
-
0
-

Ráno moudřejší večera

Řešení: přetížit operátor jako ("nečlenskou") funkci.

hu

Nahlásit jako SPAM
IP: 193.86.81.–
KIIV
~ Moderátor
+43
God of flame
9. 4. 2021   #3
-
0
-

Jinak dobre je vyblokovat implicitni konverze (tj. u konstruktoru beroucich jen jeden parametr hodit modifikator explicit). Posledni co potrebujes jsou nesrozumitelne zpravy z templatu, kde se "zahadne" pouziva tvoje trida misto floatu, ktery si tam chtel (nebo libovolneho jineho typu, ktery umis implicitne prevest na svoji tridu).

Nahlásit jako SPAM
IP: 37.48.26.–
Program vždy dělá to co naprogramujete, ne to co chcete...
9. 4. 2021   #4
-
0
-

#3 KIIV
Třída vytvořená pro jedno konkrétní užití. Ale nikdy neříkej nikdy. Takže pro budoucí použití by to smysl mělo.

hu

Nahlásit jako SPAM
IP: 193.86.81.–
Staon0
Návštěvník
17. 4. 2021   #5
-
0
-

Vzhledem k tomu, že op1 je typu MyClass, tak si jsem dost jistý, že změna operátoru na nečlenskou funkci neměla žádný podstatný význam. Ve skutečnosti problém pravděpodobně byl v tom, že třída MyClass musela mít definovanou automatickou konvezi na float. V takovém případě překladač při vyhodnocení výrazu 

vysledek = op1 + op2;

nalezl 2 operátory: float + float a MyClass ₊ MyClass. Operandy pomocí automatických operací dokázal převést na oba, a protože v obou případech použil automatickou konverzi, nedokázal se pro žádný z nich rozhodnout. (Pokud by např. našel operátor, který konverzi nevyžaduje, tak by ho vesele použil.)

Převedení operátoru na nečlenskou funkci má význam pouze proto, abyste mohl napsat 

vysledek = op2 + op1;

tzn. aby bylo možné aplikovat automatickou konverzi na levý operand. Jestli vám to nakonec začalo fungovat, tak to bylo skoro zaručeně tím, že jste odstanil některou automatickou konverzi: buď MyClass -> float nebo obráceně. Anebo jste možná operátor přetížil tak, že dokázal přijímat přímo floaty - pak by nepotřeboval automatickou konverzi a operátor by si dokázal vybrat. Jiné možné řešení (netvrdím, že doporučené) by bylo zcela odstanit operátor+ pro MyClass a nechat překladač vždy počítat ve floatech a převádět pomocí obou automatických koverzí tam a zpět.

Obecně takové praktické pravidlo v C++ džungli je "když už použiji automatickou konverzi (ono se to občas hodí), tak vždy ji mít pouze jedním směrem - buď jen tam, nebo jen zpět, ale nikdy obojí." Pokud mám konverzi oběma směry, musím být sakra opatrný. A popravdě, osobně jsem se ve své praxi setkal pouze s jedním případem, kdy to dávalo smysl.

Nahlásit jako SPAM
IP: 94.113.221.–
17. 4. 2021   #6
-
0
-

Vyřešit problém tím, že ho číslo nechám převést na float a počítat ve float a pak zpět převést, je zcela zcestný postup. Cílem bylo odstranit float jednak kvůli vyšším nárokům na strojový čas a za druhé kvůli potížím při vyhodnocování ==.  A tak vznikla třída, která představuje číslo s pevnou desetinnou čárkou na 4 desetinná místa a interně používá long a celočíselnou algebru s vyjímkou násobení, kde byl potřeba long long.

Je to na jednočipu. Kdyby to bylo na Windows, dělal bych to v C#, kde je typ decimal.

Každopádně to funguje, je to otestovaný a po cca 3 týdnech jsou problémy a neúspěšné kroky už zapomenutý.

hu

Nahlásit jako SPAM
IP: 193.86.81.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 68 hostů

Podobná vlákna

Přetypování operátorů — založil Wimby

Vynutit unikatnost — založil Jelcin

Jak vynutit obtékání — založil Návštěvník

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý