用于检查是否源自模板专业化的 C++ 概念

Ram*_*mon 3 c++ templates c++-concepts

这个 SO 答案这个提案中,我们可以看到 的实现(为了方便起见,在下面包含)std::is_specialization_of,它可以检测类型是否是给定模板的特化。

\n
template< class T, template<class...> class Primary >\nstruct is_specialization_of : std::false_type {};\n\ntemplate< template<class...> class Primary, class... Args >\nstruct is_specialization_of< Primary<Args...>, Primary> : std::true_type {};\n
Run Code Online (Sandbox Code Playgroud)\n

该提案明确指出此类型特征不受继承影响:

\n
\n

所提出的特征仅考虑专业化。由于特化与继承无关,因此当任何模板参数恰好通过继承定义时,trait\xe2\x80\x99s 结果不受影响。

\n
\n
template< class > struct B { };\ntemplate< class T > struct D : B<T> { };\n\nstatic_assert(     is_specialization_of_v< B<int>, B> );\nstatic_assert(     is_specialization_of_v< D<int>, D> );\n\nstatic_assert( not is_specialization_of_v< B<int>, D> );\nstatic_assert( not is_specialization_of_v< D<int>, B> );\n
Run Code Online (Sandbox Code Playgroud)\n

有没有一种方法可以实现确实考虑继承的东西,其行为类似于std::derived_fromBase可以是给定模板的任何专门化?比如,说std::derived_from_specialization_of

\n
template<class>   struct A {};\ntemplate<class T> struct B : A<T> {};\ntemplate<class T> struct C : B<T> {};\n\nstatic_assert(derived_from_specialization_of< A<int>, A>);\nstatic_assert(derived_from_specialization_of< B<int>, B>);\nstatic_assert(derived_from_specialization_of< C<int>, C>);\n\nstatic_assert(derived_from_specialization_of< B<int>, A>);\nstatic_assert(derived_from_specialization_of< C<int>, B>);\nstatic_assert(derived_from_specialization_of< C<int>, A>);\n
Run Code Online (Sandbox Code Playgroud)\n

它还应该支持具有多个参数和/或参数包的模板:

\n
template<class, class> struct A{};\ntemplate<typename...>  struct B{};\n
Run Code Online (Sandbox Code Playgroud)\n

Cas*_*sey 5

定义_UglyROM MSVCSTL

template <template <class...> class Template, class... Args>
void derived_from_specialization_impl(const Template<Args...>&);

template <class T, template <class...> class Template>
concept derived_from_specialization_of = requires(const T& t) {
    derived_from_specialization_impl<Template>(t);
};
Run Code Online (Sandbox Code Playgroud)

我们用它来实现[range.view]/6中的仅说明类型特征is-derived-from-view-interface

is_specialization_of请注意,这与 OP 中引用的特征具有相同的限制:它仅适用于具有所有类型参数的模板。

[演示]