Przeladowanie operatora ->, szablon, problem, zabezpieczenie

Przeladowanie operatora ->, szablon, problem, zabezpieczenie
Bumcykowy
  • Rejestracja:ponad 13 lat
  • Ostatnio:ponad 8 lat
0

Witam
Ostanio na ćwiczeniach robiliśmy szablony. Jak wiadomo operator-> da sie jedynie przeładować tak żeby zwracał wskaźnik do klasy. Jak sie zabezpieczyć przed błędem jaki niesie ze sobą użycie szablonu z typem wbudowanym ? np int.

Kopiuj
template <typename T>
class AaA
{
private :
    T *a;
public:
    T *operator->()
     {
            return a;
     }
}
 
edytowany 1x, ostatnio: Bumcykowy
Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 12 godzin
1

Nijak — użycie int w przykładzie powyżej wcale nie jest błędem.
Szablony w C++ są „na gębę”, bez możliwości łatwej kontroli z czym ich się później używa. Najwyżej kod się przestanie kompilować*, albo działać.

‌*) wyrzucając kompletnie nieczytelną litanię błędów

edytowany 2x, ostatnio: Azarien
S3
  • Rejestracja:prawie 14 lat
  • Ostatnio:około 11 lat
  • Postów:61
1

A po co Ty masz się zabezpieczać? Zrobi to za Ciebie kompilator. Jeśli wykorzystasz w tym szablonie któryś z typów wbudowanych i będziesz chciał skorzystać z operatora -> to dostaniesz błąd na poziomie kompilacji. Przeciążając taki operator jasno dajesz do zrozumienia, iż chodzi ci o klasy definiowane przez użytkownika, więc użycie typów wbudowanych jest z założenia błędem, który trzeba rozwiązywać właśnie na poziomie kompilacji.
Natomiast jeśli chciałbyś korzystać z tego szablonu dla klas i typów wbudowanych (z np. tym zastrzeżeniem, że dla typów nie będzie operatora ->) to skorzystaj z częściowej specjalizacji szablonów klas. Przykład:

Kopiuj
template <typename T, bool type = false>
class AaA
{
private :
    T *a;
public:
    T *operator->()
     {
            return a;
     }
};

template <typename T>
class AaA<T, true>
{
private :
    T *a;
public:

};

void func()
{
	AaA<std::string> obj1;
	AaA<int, true> obj2;

	obj1->empty();
}
 
edytowany 2x, ostatnio: stalk3r
Endrju
  • Rejestracja:około 22 lata
  • Ostatnio:ponad rok
1

Żeby w zrozumiały dla użytkownika tej klasy sposób zakomunikować mu, że robi źle możesz zrobić takie coś:

Kopiuj
#include <type_traits>
// ...
// konstruktor:
AaA() {
  static_assert(!std::is_fundamental<T>::value, "Nie mozna uzyc tego typu!");
}
// ...

"(...) otherwise, the behavior is undefined".
edytowany 1x, ostatnio: Endrju
RE
ciekawa rzecz, nie wiedziałem o tym wcześniej, dzięki za podzielenie się :)
Endrju
To nie jest doskonale w sumie, trzeba by chyba troszkę większą drabinkę tych is_* dorobić. Takie nowe bajery w C++11. ;-)
Azarien
a ja wciąż nie widzę powodu, by blokować użycie inta w podanym wyżej przykładzie…
S3
@Azarien z założenia, skoro definiujesz szablon, który przeciąża operator -> to właśnie zakładasz, iż specjalizacje szablonu nie będą typami wbudowanymi.
Azarien
ale ten operator jest w szablonie, a wcale nie musi być w typie który jest parametrem szablonu. nadal nie widzę tego „założenia”.
Bumcykowy
  • Rejestracja:ponad 13 lat
  • Ostatnio:ponad 8 lat
0

Pobrałem Pasje C++ i przeczytałem pierwsze 100 stron. Wszystko stało się jasne.
Jest jakieś info o nowym wydaniu Pasji ?
Dzięki za pomoc.

edytowany 1x, ostatnio: Bumcykowy

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.