[英]Parameter pack aware std::is_base_of()
是否有可能靜態斷言作為模板參數提供的類型是否實現了參數包中列出的所有類型,即。 參數包知道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的fold表達式,這變得微不足道:
template <typename Type, typename... Requirements>
class CommonBase
{
static_assert((std::is_base_of_v<Type, Requirements> && ...), "Invalid.");
};
原始答案(C ++ 11/14 ):您可以使用包擴展和某些靜態版本的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<Type, ?>::value
問號,包擴展將擴展為您獲得的值列表,即對於main中的第一行,它將擴展為static_all_of<true, true>
,第二行將是static_all_of<true, false, true>
僅供以后參考,因為我剛遇到這個問題,所以在C ++ 17中,您現在可以使用像這樣的折疊表達式:
template<typename Base, typename... Args>
constexpr auto all_base_of()
{
return (std::is_base_of<Base, Args>::value && ...);
}
static_assert(all_base_of<Base, A, B, C>());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.