Implementace operátoru []

Implementace operátoru []
« kdy: 20. 07. 2013, 18:56:33 »
Dobrý deň,
Snažím sa implementovať do môjho OOP jazyka overloading operátora []. Jedna z možností je c++ štýl:
Kód: [Vybrat]
//A)
<type> 'operator' '[' ']' '(' [params]...  ')' [qualifier]
Problém je ten, že môj jazyk má správu pamäte podobnu c#, takže funkcia nemôže večšinou vracať referenciu, takže takýto operator sa dá požiť len ako getter. Syntax môjho jazyka je odvodena od D (konštruktor sa volá this(), property sa riešia tiež ako v D pomocou atributu @property ) takže vytvoriť property this[] ako v C# sa moc nehodí.
Ďalšie riešenie čo ma napadlo je nasledovné:
Kód: [Vybrat]
//B)
<type> 'operator' '[' [params]... ']' '(' ')' [qualifier]      //getter     
<type> 'operator' '[' [params]... ']' '(' <param> ')' [qualifier]      //setter     
//alebo s '=':
<type> 'operator' '[' [params]... ']' '=' '(' <param> ')' [qualifier]      //setter

//priklad:
class C{
    int[] x;
    int operator [ size_t index ] () {return x[index];}
    void operator [ size_t index ]( int value) {x[index] = value;}    // '=' by tam v podstate ani nemuselo byť
    //alebo s '=':
    void operator [ size_t index ] = ( int value) {x[index] = value;}    // '=' by tam v podstate ani nemuselo byť
}
Toto riešenie sa my zatial najviac pozdava. (je to v podstate C# property this[] s inou syntaxou)

Ďalej ma napadol taký mix C++ a D:
Kód: [Vybrat]
//C)
<type> 'operator' '[' [params]... ']' '(' ')' [qualifier]      //getter     
<type> 'operator' '[' [params]... ']' <unar_op> '('  ')' [qualifier]      //setter, napr   obj[index]++,
<type> 'operator' '[' [params]... ']' <bin_op> '(' <param> ')' [qualifier]      //setter, napr obj[index]+= tmp; obj[index]= tmp;

//priklad:
class C{
    int[] x;
    int operator [ size_t index ] () {return x[index];}
    void operator [ size_t index ]=( int value) {x[index] = value;}
    void operator [ size_t index ]+=( int value) {x[index] += value;}
    void operator [ size_t index ]++() {x[index]++;}     //toto sa my zda už prehnané

    //sem by sa potom hodil daky generator (určituú formu compile time templatov ako v D čo je ďalšia práca navyše lebo planujem mať zaťial len templaty ako v C#, čiže priamo v bytecode)

}
Toto riešenie rozširuje možnosť B) a spája aj iné operátory ako '=' s indexovacím  '[]'. Tu mám na vás jednu otázku. Požívate často nasledovný kód:
Kód: [Vybrat]
  obj[index] += expr;
  obj[index] -= expr;
  obj[index] op= expr;    //op je iny operator ktory sa da spája s '='.
Či sa vobec oplati zaoberať takymto až "extrémnym" overloadingom.
Prípadne stretli ste sa s inou syntaxou overloadingu operatorov ktorá by sa viac hodila?
« Poslední změna: 21. 07. 2013, 20:12:48 od Petr Krčmář »


JSH

Re:operator []
« Odpověď #1 kdy: 21. 07. 2013, 16:00:00 »
Odpověď ber s rezervou, protože o tom jazyce moc nevím.

Proč by funkce neměla mít možnost vracet referenci? O C# moc nevím, ale mám pocit že se tam s referencemi pracuje furt. Je to tak, že tvůj jazyk nezvládá referenci na referenci (ukazatel na ukazatel)?

Řešení C je podle mně hrozně komplikované. Spojuje dvě nezávislé věci (rozhraní kontejneru a rozhraní prvku) do jednoho bastlu. Navíc stále neřeší kód typu
Kód: [Vybrat]
a[i].metoda(x,y,z)
, který občas používám.

Je možné i vracet pomocný objekt, který bude mít operátor=, případně další.

Ale závisí to na spoustě vlastností toho jazyka, které neznám. Co dělá operátor přiřazení? Modifikuje vnitřek objektu, nebo jen nastaví referenci na jiný objekt? Jsou operátory jako += jen syntaktický cukr, nebo se chovají úplně jinak než prosté přiřazení? Bez podrobností tady asi moc dobré odpovědi nedostaneš.

Re:operator []
« Odpověď #2 kdy: 21. 07. 2013, 17:52:51 »
Vracať referenciu nie je možné kvôly nasledovnému dôvodu:
(pod referenciou myslým referenciu na typ ktory nie spravovany s GC (primitivne typy a struktury, v podstate tak ako v D))

Kód: [Vybrat]
//príklad v D:

import std.stdio;

ref int mask(ref int i){
return i;
}

ref int fnc(){
int i = 2;
return mask(i);
}

void print(int x, ref int i){
writeln(i);
}

void main(){
print(3, fnc());
}


Ja nemám problem to implementovať, len sa neviem rozhodnúť aký  syntaktický cukor použiť ;D. Poznám relatívne málo jazykov a väčšinou také ktoré majú syntax odvodenu od C/C++. Nakoniec asi použiem možnosť (B), s možnosť (C) to asi moc komplikuje.

JSH

Re:Implementace operátoru []
« Odpověď #3 kdy: 22. 07. 2013, 09:25:37 »
Proč by to nemělo být možné? Nějak v tom  kódu ten důvod nevidím. Vidím tam jen "dangling" referenci, což je imho jen bug. Vracet referenci má samosebou smysl pouze na objekt, který existuje i mimo tělo té funkce.

Re:Implementace operátoru []
« Odpověď #4 kdy: 03. 08. 2013, 08:21:43 »
Ja som nepopisal podrbne funkcnost mojho jazyka lebo som len navrhoval syntax (skor som ukopiroval existujuci uz z inych jazykov :) ). Samozrejme ty si nemohol vedie ake ma mat vlastnost ten jazyk (napr: neumoznit pristup do poskodenej/neplatnej pamete ). Zrejme som mal jazyk vjac popisat alebo sa lepsie vyjadrit ze chcem len pomoct z navrhom syntaxe. Nakonie som pouzil moznost B.