Niejawna konwersja

0

http://ideone.com/m03iTC

Rozumiem, ze podczas wywołania (a+1) mogą stać się dwie rzeczy:
a+T(1)
int(a) + 1
Tak widzi to kompilator i dlatego nie wie, czy zastosowac operator+(T, T), czy operator+(int, int)
okej, jasne.
Ale jakim cudem on chce zrobic konwersje z T na inta? I dlaczego operator bool wszystko psuje?

1
#include <iostream>

class T 
{
public:
    int a, b;
    T (int _a = 0, int _b = 0) : a(_a), b(_b) { }

    friend T operator+ (const T &a, const T &b) {
        return T(a.a + b.a, a.b + b.b);
    }
};

int main () 
{
    T a(1, 3);
    std::cout << (a + 1).a << ' ' << (a + 1).b;
    return 0;
}

To działa. Nie ma niespodzianki.
#include <iostream>

class T 
{
public:
    int a, b;
    T (int _a = 0, int _b = 0) : a(_a), b(_b) { }

    friend T operator+ (const T &a, const T &b) {
        return T(a.a + b.a, a.b + b.b);
    }

    operator bool () { return (this->b != 0 || this->a != 0); }
};

int main () 
{
    T a(1, 3);
    std::cout << (a + 1).a << ' ' << (a + 1).b;
    return 0;
}

To nie działa. T jest konwertowane na bool, a bool na int.
#include <iostream>

class T 
{
public:
    int a, b;
    T (int _a = 0, int _b = 0) : a(_a), b(_b) { }

    friend T operator+ (const T &a, const T &b) {
        return T(a.a + b.a, a.b + b.b);
    }

    operator int() = delete;
};

int main () 
{
    T a(1, 3);
    std::cout << (a + 1).a << ' ' << (a + 1).b;
    return 0;
}

To NIE działa! Surprise!!!

= delete działa nie do końca (przynajmniej dla mnie) intuicyjnie. To nie mówi, że ta funkcja nie istnieje. To mówi, że ta funkcja istnieje, ale nie może zostać użyta. Dlatego funkcje = delete też są brane podczas dopasowania przeciążania.

void foo(double x) {}
void foo(int x) = delete;   // zakomentuj to i kod się skompiluje

int main() 
{
	foo(0);
}
0

No ekstra, ale jak to zaimplementować, żeby był zarówno operator bool() jak i działający operator+

2
explicit operator bool ()
0

To jest przykład nadgorliwości z definicją operatora. (zresztą IMO własne operatory to samo zło).
Po kiego grzyba definiować operator konwersji do bool, który jest explicit? To jest bezsensu.
Dużo lepiej zdefiniować normalną nazwaną funkcję (np: bool isZero() const), będzie czytelniej.

Innym rozwiązaniem, jest skrócenie dystansu konwersji i zdefiniowanie mieszanych operatorów dodawania.
http://ideone.com/zHLBSb

1 użytkowników online, w tym zalogowanych: 0, gości: 1