Я пытаюсь написать код, который эффективно:
template <typename... Mixins>
class Checker : public Mixins... {
public:
template<typename... Args>
Checker(Args&&... args) : Mixins(std::forward<Args>(args))... { }
bool check(void) {
bool tests = true;
// TODO: for each Mixins that has Mixin::check
{
tests = tests && Mixin::check();
}
if (!tests) {
// TODO: for each Mixin that has Mixin::handle
{
Mixin::handle()
}
}
return tests
}
};
Я просто не знаю, как сделать циклы над теми миксинами, которые удовлетворяют заданным условиям. Я пробовал различные решения для итерации и для семантики типа enable_if, но, похоже, ничего не компилируется.
дополнительный
Итак, то, что я пробовал до сих пор: виза vi для каждой базовой рекурсии и удаление функции SFINAE, это следующее, что не компилируется:
template <typename C, typename... Mx>
struct do_checks;
template <typename C>
struct do_checks<C> {
static bool check(C *) {
return true;
}
};template <typename C, typename E, typename... Mx>
struct do_checks<C, E, Mx...> {
struct general_ { };
struct special_ : general_ { };
template <typename> struct int_ { typedef int type; };
template <typename F, typename int_<decltype(F::check)>::type = 0>
static bool check(C *ptr, special_) {
if (!ptr->F::check()) {
return false;
}
return do_checks<C, Mx...>::check(ptr);
}
template <typename F>
static bool check(C *ptr, general_) {
return do_checks<C, Mx...>::check(ptr);
}
};
Где F должно быть E. Я не знаю, как сказать компилятору скомпилировать первую «проверку», если тип int_ имеет тип, и второй, если он не имеет.
Вы можете создать черту с именем has_check
который возвращает true для типа, который имеет статический check()
метод.
namespace detail
{
template<class T, class = decltype(T::check())>
std::true_type has_check_impl(void*);
template<class T>
std::false_type has_check_impl(...);
}
template<class T>
struct has_check : decltype(detail::has_check_impl<T>(nullptr)) { };
Затем вы можете использовать его в качестве предиката std::enable_if
включить / отключить перегрузку, если у нее есть метод:
private:
template<class T, class...>
using first = T;
template<class T = void,
class =
first<T,
typename std::enable_if<has_check<Mixins>::value, T>::type...>>
static void foo(void*)
{
auto x{ (0, Mixins::check(), 0)... };
(void)x;
}
static void foo(...)
{
auto x{ (0, Mixins::handle(), 0)... };
(void)x;
}
public:
static void check() {
foo(nullptr);
}
Других решений пока нет …