参数包感知 std::is_base_of() [英] Parameter pack aware std::is_base_of()

查看:35
本文介绍了参数包感知 std::is_base_of()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有可能静态断言作为模板参数提供的类型是否实现了参数包中列出的所有类型,即.参数包感知 std::is_base_of()?

Is there a possibility to have a static assertion whether a type provided as template argument implements all of the types listed in the parameter pack ie. a parameter pack aware std::is_base_of()?

template <typename Type, typename... Requirements>
class CommonBase
{
    static_assert(is_base_of<Requirements..., Type>::value, "Invalid.");
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            parameter pack aware version of std::is_base_of()
public:
    template <typename T> T* as()
    {
        static_assert(std::is_base_of<Requirements..., T>::value, "Invalid.");
        return reinterpret_cast<T*>(this);
    }
};

推荐答案

C++17 更新:使用 C++17 的折叠表达式,这几乎变得微不足道:

Update for C++17: With C++17's fold expressions this becomes almost trivial:

template <typename Type, typename... Requirements>
class CommonBase
{
    static_assert((std::is_base_of_v<Type, Requirements> && ...), "Invalid.");
};

原始答案 (C++11/14):您可能会使用包扩展和一些静态版本的 std::all_of:

Original Answer (C++11/14): You might use pack expansion and some static version of std::all_of:

template <bool... b> struct static_all_of;

//implementation: recurse, if the first argument is true
template <bool... tail> 
struct static_all_of<true, tail...> : static_all_of<tail...> {};

//end recursion if first argument is false - 
template <bool... tail> 
struct static_all_of<false, tail...> : std::false_type {};

// - or if no more arguments
template <> struct static_all_of<> : std::true_type {};

template <typename Type, typename... Requirements>
class CommonBase
{
    static_assert(static_all_of<std::is_base_of<Type, Requirements>::value...>::value, "Invalid.");
    //                                               pack expansion:      ^^^
};

struct Base {};
struct Derived1 : Base {};
struct Derived2 : Base {};
struct NotDerived {};

int main()
{
  CommonBase <Base, Derived1, Derived2> ok;
  CommonBase <Base, Derived1, NotDerived, Derived2> error;
}

包扩展将扩展到您通过在 Requirements... 中插入每个类型以获得std::is_base_of 中的问号的值列表::value,即对于 main 中的第一行,它将扩展为 static_all_of,对于第二行,它将扩展为 static_all_of

The pack expansion will expand to the list of values you get by inserting every type in Requirements... for the question mark in std::is_base_of<Type, ?>::value, i.e. for the first line in main it will expand to static_all_of<true, true>, for the second line it will be static_all_of<true, false, true>

这篇关于参数包感知 std::is_base_of()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆