• 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

VPS Starter Arubacloud
+1 głos
323 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,100 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 181 wizyt
0 głosów
1 odpowiedź 310 wizyt
pytanie zadane 25 kwietnia 2022 w C i C++ przez Mavimix Dyskutant (8,390 p.)
0 głosów
2 odpowiedzi 2,793 wizyt

92,452 zapytań

141,262 odpowiedzi

319,085 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...