Szablony klas - jak wyspecjalizować metody zależnie od typu szablonu?

0

mam taki problem

jak mam

template <typename T>
class A
{
     private:
            T x;
     public:
            void show(void);
}

i kiedy zrobię

A<int> X
a<int *> X

to hce zeby funkcja show była inna kiedy robię wskaźniki i inna kiedy typy niewskaźnikowe.

czy można wyspecjalizować tylko jedna metodę wewnątrz szablonu klasy.

1

Tak i nie.

Nie możesz wyspecjalizować pojedynczej funkcji, ani "wciągnąć" implementacji podstawowej do specjalizacji.

template<typename T>
struct X{
	void foo(){}

	int bar(){
		return 1;
	}
};

template<typename T>
struct X<T*>{

	// a foo?

	int bar(){
		return 2;
	}
};

Możesz to ominąć poprzez ustalenie wspólnej klasy bazowej:

struct Baza{
    
    void foo(){}
};

template<typename T>
struct X : Baza{
    int bar(){
        return 1;
    }
};

template<typename T>
struct X<T*> : Baza{
    int bar(){
        return 2;
    }
};

Jeśli z jakiegoś powodu nie chcesz rozbijać implementacji klasy na kilka części możesz użyć std::enable_if lub metody znanej jako tag dispatching. enable_if jest "łatwiejszy" dla pojedynczej zmiennej, ale ogółem nie jest polecanym rozwiązaniem ponieważ ilość przeładowań dla różnych kombinacji rośnie wykładniczo, a już dla jednej wygląda średnio.

enable_if:

template<typename T>
struct X{

    void foo(){}

    template<typename U=T>
    typename enable_if<!is_pointer<U>::value,int>::type
    bar(){
        return 1;
    }

    template<typename U=T>
    typename enable_if<is_pointer<U>::value,int>::type
    bar(){
        return 2;
    }
};

I tag dispatch:

template<typename T>
struct X{

    void foo(){}

    int bar(){
        return bar_impl(typename is_pointer<T>::type{});
    }

private:

    int bar_impl(true_type){
        return 2;
    }

    int bar_impl(false_type){
        return 1;
    }

};

Jest to rozwiązanie w/g mnie najlepsze, ponieważ pozwala wyraźnie (i czytelnie) określić która implementacja kiedy ma się wykonać.

Każde z powyższych rozwiązań powinno wypisać

1
2

dla poniższej funkcji main:

int main()
{
    X<int> a;
    X<int*> b;

    cout << a.bar() << endl;
    cout << b.bar() << endl;
    return 0;
}

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