C ++ Mixins有2种功能类型

时间:2014-02-21 21:03:52

标签: c++ mixins

我正在尝试编写有效的代码:

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
    }    
};

我只是不知道如何在满足指定成员条件的Mixins上进行循环。我已经尝试了迭代和enable_if类型语义的各种解决方案,但似乎没有编译。

其他

那么,到目前为止我所尝试过的签证vi for-each base recursion和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_有一个类型,我不知道如何告诉编译器编译第一个“check”,如果没有,则不知道如何编译第二个“check”。

1 个答案:

答案 0 :(得分:2)

您可以创建一个名为has_check的特征,该特征对于具有静态check()方法的类型返回true。

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);
    }