Witam!
Mam taki problem, że bardzo pasowałoby mi zrobić coś takiego, że robię sobie szablon klasy, specjalizuję go dla pewnego typu bazowego. To jest proste i oczywiste, właściwy problem zaczyna się teraz, bo bardzo by mi pasowało by na tym szablonie mogły pracować typy pochodne bez konieczności jego zmiany?
Wydaje mi się, że jest to niemożliwe w C++, ale lepiej się upewnić, bo zaoszczędziłoby mi to wiele roboty.
0
1
Co znaczy "na tym szablonie mogły pracować"?
"specjalizuję go dla pewnego typu bazowego" - czy na pewno mówimy o szblonach?
0
Rzuć konkretnym przykładem, bo też nie bardzo rozumiem o co chodzi.
0
Jesli chodzi Ci o ograniczenie parametru generycznego do jakiejstam hierarchi, to w C++ chyba nie ma czegos takiego, anyway mozna zrobic tak:
#include <iostream>
using namespace std;
class IComparable {
public:
virtual bool Equal(const IComparable&) = 0;
typedef int IsComparable;
};
class Foo : public IComparable {
public: bool Equal(const IComparable&) {
return true;
}
};
template <typename Comparable>
void compare(const Comparable& cmp, const Comparable& cmp2) {
typedef typename Comparable::IsComparable Guard;
}
int main() {
Foo f;
compare(f, f);
//compare(10, 20); // wyrzuci error compile-time
return 0;
}
No i pewnie Boost cos ma juz gotowego zrobionego, co nie wyglada tak kiepsko jak to powyzej :P
1
Taki mechanizm jest możliwy do zaimplementowania w C++ przy użyciu std::enable_if i std::is_base_of, przykład poniżej. Ofx, zawsze możesz użyć prostszego rozwiązania zaproponowanego przez @n0name_l.
#include <iostream>
#include <string>
#include <type_traits>
#include <memory>
struct A { virtual char getName() const { return 'A'; } };
struct B : public A { virtual char getName() const override { return 'B'; } };
struct C : public A { virtual char getName() const override { return 'C'; } };
template <typename T, typename Enable = void>
struct D
{
static void foo(const T& t, std::ostream& out = std::cout) { out << "D" << std::endl; }
};
template <typename T>
struct D<T, typename std::enable_if<std::is_base_of<A, T>::value>::type>
{
static void foo(const T& t, std::ostream& out = std::cout) { out << t.getName() << std::endl; }
};
int main()
{
std::unique_ptr<A> a(new A);
std::unique_ptr<A> b(new B);
std::unique_ptr<A> c(new C);
D<A>::foo(*a);
D<A>::foo(*b);
D<A>::foo(*c);
D<int>::foo(5);
return 0;
}
Output będzie wyglądał w ten sposób:
A
B
C
D