Начиная с C ++ 11 вам не нужно Boost или static_assert
. C ++ 11 представляет is_base_of
и enable_if
. C ++ 14 вводит вспомогательный тип enable_if_t
, но если вы застряли в C ++ 11, вы можете просто использовать вместо него enable_if::type
.
Альтернатива 1
Дэвид Родригес решение может быть переписано следующим образом:
#include <type_traits>
using namespace std;
template <typename T>
enable_if_t<is_base_of<Base, T>::value, void> function() {
// This function will only be considered by the compiler if
// T actualy derived from Base
}
Альтернатива 2
Начиная с C ++ 17, мы имеем is_base_of_v
. Решение можно переписать так:
#include <type_traits>
using namespace std;
template <typename T>
enable_if_t<is_base_of_v<Base, T>, void> function() {
// This function will only be considered by the compiler if
// T actualy derived from Base
}
Альтернатива 3
Вы также можете просто ограничить весь шаблон. Вы можете использовать этот метод для определения целых классов. Обратите внимание, как был удален второй параметр enable_if_t
(ранее он был установлен в void). Его значение по умолчанию на самом деле void
, но это не имеет значения, поскольку мы его не используем.
#include <type_traits>
using namespace std;
template <typename T,
typename = enable_if_t<is_base_of_v<Base, T>>>
void function() {
// This function will only be considered by the compiler if
// T actualy derived from Base
}
Из документации параметров шаблона мы видим, что typename = enable_if_t...
- это параметр шаблона с пустым именем. Мы просто используем его, чтобы убедиться, что определение типа существует. В частности, enable_if_t
не будет определено, если Base
не является основанием T
.
Приведенный выше метод приведен в качестве примера в enable_if
.