Я хочу создать черту / интерфейс, например, is_good
, и реализовать мои общие функции, ориентированные на его спецификацию.
Я придумаю следующий код, которому помогают некоторые онлайн-ресурсы, касающиеся SFINAE.
template<class C>
struct is_good: std::false_type
{
};
template<>
struct is_good<A<double, 2>>: std::true_type
{
};
template<>
struct is_good<B<double, 2, 3>>: std::true_type
{
};
template<template<class> class C, class T>
using check_constraints = std::enable_if_t<C<T>::value, bool>;
}
Мои общие функции определены следующим образом:
template<class T, template<class> class C = is_good,
typename = check_constraints<C, T>>
void compute(const T& t) {}
При использовании
// works
compute(A<double,2>());
compute(B<double,2, 3>());
// should not compile.
compute(B<double,5, 6>());
Однако, это кажется немного громоздким.И я должен добавить
template<class T, template<class> class C = is_good,
typename = check_constraints<C, T>>
ко всем моим функциям, которые я планирую обобщить.
Есть ли лучшие способы?
Обновление
Основой этого вопроса является то, что я знаю, что тело моих функций работает с типом A
& B
& C
, как я могу определить свои функции?
Например, на других языках, возможно, вы можете сделать
using T = Union{A, B, C};
void compute(T t){...}
# works with A
compute(A());
# works with B
compute(B());
независимо от того, как выглядит A, B, C
.