• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed C++ przypisanie obiektów typu dwóch różnych klas szablonowych

Object Storage Arubacloud
+1 głos
338 wizyt
pytanie zadane 17 czerwca 2019 w C i C++ przez dawid2002 Mądrala (5,190 p.)
zamknięte 17 czerwca 2019 przez dawid2002

Witam! Ostatnio czytając kurs C++ K.Kuczmarskiego autor tego kursu powiedział, że klasy szablonowe konkretyzowane innym zestawem parametrów są zupełnie odmiennymi typami. Zatem na przykładzie szablonu TStaticArray oraz jej obiektów a10Intow i a20Floatow przedstawił kod tego szablonu, który za pomocą przeciążonego operatora przypisania powoduje, że przypisanie tych odmiennych typów jest możliwe:

template <typename T, unsigned N> class TStaticArray
{
	T m_aTablica[N];

public:

	const unsigned ROZMIAR = N;

	T& operator[](unsigned uIndeks)
	{
	    return m_aTablica[uIndeks];
    }



    template <typename T2, unsigned N2>
    TStaticArray& operator=(const TStaticArray<T2, N2>& aTablica)
    {
        if (&aTablica != this)
        {
            if (N2 > N)
                cerr << "za duza tablica" << endl;

            for (unsigned i = 0; i < N2; ++i)
                (*this)[i] = aTablica[i];     	// (*this) – odwolanie do obiektu
        }
        return *this;
    }

};

Wszystko ładnie działa aż do momentu, gdy pojawi się zapis:

int main()
{
    TStaticArray<float,5> ob1;
    TStaticArray<int,4> ob2;

    ob1 = ob2;
     
     return 0;
}


Wtedy VS pokazuje błąd (dla instrukcji "&aTablica != this"):

"!=": brak konwersji z "TStaticArray<float,5> *" na "const TStaticArray<int,4> *"  

Oraz (dla: "(*this)[i] = aTablica[i];"):

dwuargumentowy "[": nie znaleziono żadnego operatora, który przyjmuje lewostronny operand typu "const TStaticArray<int,4>" (lub nie istnieje akceptowalna konwersja)

Zatem żeby rozwiązać problem zmieniłem w kodzie (zmiany są podświetlone):

template <typename T, unsigned N> class TStaticArray
{
public:

	T m_aTablica[N];      // Niestety musiałem uczynić go publicznym wskaźnikiem :(

	const unsigned ROZMIAR = N;

	T& operator[](unsigned uIndeks)
	{
	    return m_aTablica[uIndeks];
        }


    template <typename T2, unsigned N2>
    TStaticArray& operator=(const TStaticArray<T2, N2>& aTablica)
    {
        if ((void*)&aTablica != (void*)this)
        {
            if (N2 > N)
                cerr << "za duza tablica" << endl;

            for (unsigned i = 0; i < N2; ++i)
                (*this)[i] = aTablica.m_aTablica[i];
        }
        return *this;
    }

};

Mój problem polega na tym, że zmiany, które wprowadziłem w kodzie są niezbyt ładne (np: publiczny wskaźnik). W taki razie jak powinien wyglądać przyzwoity oraz działający kod?

Z góry bardzo dziękuje za pomoc!

EDIT:

Póki co udało mi się częściowo rozwiązać problem używając zaprzyjaźniania:

// (...)
template<typename,unsigned> friend class TStaticArray;

	T m_aTablica[N];

public:
// (...)

Aczkolwiek nadal muszę używać tej formy:

(*this)[i] = aTablica.m_aTablica[i];

Zamiast tej:

(*this)[i] = aTablica[i];

PS.

Proszę nie wincie mnie za to, że zadaje to pytanie, po prostu się uczę dopiero!

komentarz zamknięcia: znam już odpowiedź
komentarz 17 czerwca 2019 przez mokrowski Mędrzec (155,460 p.)
Ok, ogólnie firend jest zły. Ale bardziej precyzyjnym pytaniem było by... co chcesz (dokładnie) osiągnąć? (bo masz jeszcze kilka błędów w kodzie)

1 odpowiedź

+1 głos
odpowiedź 17 czerwca 2019 przez adrian17 Ekspert (344,860 p.)
wybrane 17 czerwca 2019 przez dawid2002
 
Najlepsza

"!=": brak konwersji z "TStaticArray<float,5> *" na "const TStaticArray<int,4> *"  

Chodzi o to porównanie:

if (&aTablica != this)

Jeśli typy są różne, to porównanie nie jest możliwe (nawet gdyby było, to byłoby zawsze false). Jeśli są równe, to ma sens. Może zrób osobne przeładowanie dla tego samego typu?

dwuargumentowy "[": nie znaleziono żadnego operatora, który przyjmuje lewostronny operand typu "const TStaticArray<int,4>" (lub nie istnieje akceptowalna konwersja)

To wygląda na prosty problem z const correctness. Zrób dwa przeładowania operatora[]:

    T& operator[](unsigned uIndeks)
    {
        return m_aTablica[uIndeks];
    }
    const T& operator[](unsigned uIndeks) const
    {
        return m_aTablica[uIndeks];
    }

 

komentarz 17 czerwca 2019 przez dawid2002 Mądrala (5,190 p.)

Wielkie dzięki! yes

Ja jeszcze dodatkowo napisałem przeładowanie dla operatora !=

template<typename Type,unsigned NN> bool operator!=(const TStaticArray<Type,NN> ob)
{
     return (static_cast<void*>(this) != &ob);
}

if(*this != aTablica)    // pięknie działa :) 

 

Podobne pytania

0 głosów
2 odpowiedzi 184 wizyt
0 głosów
1 odpowiedź 326 wizyt
pytanie zadane 25 kwietnia 2022 w C i C++ przez Mavimix Dyskutant (8,390 p.)
0 głosów
2 odpowiedzi 2,841 wizyt

92,565 zapytań

141,416 odpowiedzi

319,598 komentarzy

61,948 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...