Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;2种功能类型的混合物_C++_Mixins - Fatal编程技术网

C++ C++;2种功能类型的混合物

C++ C++;2种功能类型的混合物,c++,mixins,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 t

我试图编写有效的代码:

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
    }    
};
模板
类检查器:公共混合。。。{
公众:
模板
检查器(Args&&…Args):混合(std::forward(Args))…{}
布尔支票(作废){
布尔检验=真;
//TODO:对于具有Mixin::check的每个Mixin
{
测试=测试和混合::检查();
}
如果(!测试){
//TODO:对于具有Mixin::handle的每个Mixin
{
Mixin::handle()
}
}
返回测试
}    
};
我只是不知道如何在那些满足指定成员条件的混合上进行循环。我已经尝试了各种迭代和enable_if类型语义的解决方案,但似乎什么也编译不了

附加的

因此,到目前为止,我在visa 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);
    }
};
模板
结构检查;
模板
结构检查{
静态布尔检查(C*){
返回true;
}
};
模板
结构检查{
结构通用{};
特殊结构:一般结构{};
模板结构int{typedef int type;};
模板
静态布尔检查(C*ptr,专用){
如果(!ptr->F::check()){
返回false;
}
返回do_检查::检查(ptr);
}
模板
静态布尔检查(C*ptr,常规){
返回do_检查::检查(ptr);
}
};

其中F应该是E。如果int有类型,我不知道如何告诉编译器编译第一个“check”,如果int没有类型,则编译第二个“check”。

您可以创建一个名为
has\u 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)) { };

您希望Mixin的具体内容是什么?我在代码中找不到任何有效的声明。可能是您混淆了动态和静态代码求值吗?@πάνταῥεῖ, 我认为OP试图做的是在每个基上调用
check()
方法class@BrianBi ... 当然,这样做是行不通的@πάνταῥεῖ 不,但我认为OP知道代码是错误的,但我只是想传达他们想要的想法,@Brian是对的,我想为任何有该方法的基类调用检查,但不为任何没有该方法的基类调用检查,所以我不必为没有任何要检查的类调用很多无OP方法。是的,TODO是我想弄清楚的。如何编写代码,填写TODO,以实现所描述的内容?我认为@TimeHorse实际上希望在所有混入中运行
handle
,如果
check
s failedIt中的任何一个都需要我花一段时间来重构代码,以遵循建议的范例,但我确实计划尝试一下,如果可行,我会很高兴地奖励分数。可能要到星期一才能开始。对不起(@TimeHorse不用担心。很高兴我能帮上忙。再次感谢您的耐心。GCC似乎没有正确编译decltype,因为我知道GCC对它的支持仍在减弱。当我试图从has\u check中获取constexpr值时,编译器阻塞。但是我看到您在派生has\u check时已剥离了true\u type或false\u type的类型,两者都是其中有GCC 4.8和4.7中的constexpr值代码,所以我只能猜测declexpr是错误的。有什么想法吗?另外,我去掉了静态,因为我需要每个Mixin都有指向其POD结构的this指针。
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);
    }