Poczytałem sekcję 13.5 po refuting the notion, że wbudowane operatory nie biorą udziału w przeciążeniu i zauważyłem, że nie ma sekcji o operator->*
. Jest to tylko ogólny operator binarny.Czy wolny operator -> * przeładowuje zło?
Jego bracia, operator->
, operator*
, i operator[]
, wszyscy muszą być niestatycznymi funkcjami członka. Wyklucza to definicję przeciążenia funkcji swobodnej dla operatora, zwykle używanego do uzyskania odniesienia z obiektu. Ale niezbyt często operator->*
jest pominięty. W szczególności, operator[]
ma wiele podobieństw. Jest binarny (brakowało mu złotej szansy na uczynienie go n-ary) i akceptuje jakiś kontener po lewej i jakiś rodzaj lokalizatora po prawej. Jego sekcja zasad specjalnych, 13.5.5, wydaje się nie mieć żadnego rzeczywistego skutku, z wyjątkiem zakazu wolnych funkcji. (I to nawet ograniczenie wyklucza poparcia dla przemienności!)
Tak więc, na przykład, jest to perfectly legal:
#include <utility>
#include <iostream>
using namespace std;
template< class T >
T &
operator->*(pair<T,T> &l, bool r)
{ return r? l.second : l.first; }
template< class T >
T & operator->*(bool l, pair<T,T> &r) { return r->*l; }
int main() {
pair<int, int> y(5, 6);
y->*(0) = 7;
y->*0->*y = 8; // evaluates to 7->*y = y.second
cerr << y.first << " " << y.second << endl;
}
Łatwo znaleźć zastosowania, ale składnia alternatywa raczej nie będzie tak źle. Na przykład, skalowane indeksów dla vector
:
v->*matrix_width[2][5] = x; // ->* not hopelessly out of place
my_indexer<2> m(v, dim); // my_indexer being the type of (v->*width)
m[2][5] = x; // it is probably more practical to slice just once
Czy komisja standardy zapomnieć, aby temu zapobiec, było to uważane za brzydkie niepokoić, czy są przypadki użycia świata rzeczywistego?
punkt danych: Coneau (http://www.comeaucomputing.com/tryitout/) odrzuca kod nawet po usunąłem '' a pierwszy operator: 'błąd: żaden operator „-> * "pasuje do tych argumentów" –
sbi
@sbi: Comeau było pierwszym miejscem, które odwiedziłem, ale nadal mam otwartą kartę ... Jedyny kod, który wprowadziłem przed przejściem do GCC 4.5, to "struct x {int y;}; int & ope rator -> * (x & l, int r) {return l.y; } void f() { x q; int i i = q -> * 3; } "- i zwraca sukces dla głównego przykładu minus wszystko zależne od tego pierwszego przeciążenia zależnego od typu. – Potatoswatter
Nie wiem, dlaczego operator -> * może być przeciążony w ten sposób, ale na pewno wygląda brzydko! trzymaj się z dala od tego samego powodu, co przeciążenie przecinkiem - nie wygląda na intuicyjny C++ – AshleysBrain