Страницы

Поиск по вопросам

четверг, 12 декабря 2019 г.

Как задать ограничения на параметры шаблонных классов?

#cpp #шаблоны_с++


Есть абстрактный класс M и классы A, B и C, для которых М - родительский класс, и
в них реализованы все абстрактные методы класса М.
Нужно создать шаблонный класс

template  class S{ ... };


в котором качестве шаблона используются классы A, B или C.
Можно как-то указать, что M должен быть родительским классом для Т?
    


Ответы

Ответ 1



Вас спасет std::is_base_of: struct M {}; struct A: public M {}; struct B {}; template::value>> struct S {}; int main(int argc, const char * argv[]) { S a; S b; }

Ответ 2



Один из способов - это просто объявить, например, typedef для базового класса шаблонного параметра внутри шаблонного класса. Если шаблонный параметр не имеет такого базового класса, то будет выдано сообщение об ошибке. Например, #include class M { virtual void f() const = 0; }; class A : public M { virtual void f() const { std::cout << "A" << std::endl; } }; class B { }; template class S { typedef typename T::M Base; }; int main() { S
s1; // S s2; return 0; } Если раскомментировать в этой программе закомментированное предложение, то компилятор выдаст сообщение об ошибке.

Ответ 3



А если у вас старый компилятор, то можно пойти длинным путем: class M { virtual void f() const = 0; }; class A : public M { virtual void f() const { std::cout << "A" << std::endl; } }; class B { }; template class IsDerivedFrom { class No {}; class Yes { No no[2]; }; static Yes Test(B*); static No Test(...); public: enum { Is = sizeof(Test(static_cast(0))) == sizeof(Yes) }; }; template ::Is> class S { }; template class S { S() { char * p = (int*)0; } }; int main() { S
s1; S s2; return 0; } Зато работает на старых компиляторах, которые не знают C++ 11.

Ответ 4



Можно использовать std::is_base_of: #include #include class M { public: virtual void f() = 0; }; class A: public M { public: virtual void f() { std::cout << "class a\n"; } }; class B { public: virtual void f() { std::cout << "class b\n"; } }; template::value>::type> class S { public: T t; void f() { this->t.f(); } }; int main() { S
a; //S b; return 0; } Если раскомментировать S b, то выдастся ошибка при компиляции.

Комментариев нет:

Отправить комментарий