четверг, 17 ноября 2016 г.

Использование is_base_of и enable_if и детектирование типов во время компиляции

Допустим у нас есть некая функция, которая должна быть определена только для наследников определенного класса. Можно сделать это в рантайме, но детектирование типов в рантайме это дорого и к тому же некрасиво. C++11 предлагает более красивое решение.
#include <iostream>
#include <type_traits>
 
class A 
{
public:
    virtual void do_work() = 0;
};
 
class B : public A 
{
public:
    void do_work() override { std::cout << "B::do_work()" << std::endl; };
};
 
class C
{
public:
    void do_work() { std::cout << "C::do_work()" << std::endl; };
};
 
template<typename T>
typename std::enable_if<std::is_base_of<A, T>::value, void>::type
execute_work(T &t)
{
    t.do_work();
}

UPD 03.12.2016:

можно сделать это гораздо проще:
//...
template<typename T>
bool execute_work(T &t)
{
    static_assert(std::is_base_of<A, T>::value, "T must be subclass of A");
    t.do_work();
}
 
int main()
{
    B b;
    C c;
    execute_work(b); //OK
    execute_work(c); //compile error
}
И теперь у нас компилятор будет выдавать именно то сообщение, которое мы указали в static_assert

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

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