小问题
我如何在编译时检查一个(编辑: 未实例化的)类模板是否从 C++17 的第一个模板参数继承?
长问题
我想通过以下方式构造一些东西来确定类模板是否继承自其(第一个)模板参数:
template<template<typename> class TemplateClass>
struct template_parameter_is_base_of
{
/* Implementation */
};
理想情况下,template_parameter_is_base_of
可以这样使用:
template<typename T> struct WithParent : T { /* Implementation */ };
template<typename T> struct WoutParent : { /* Implementation */ };
static_assert(template_parameter_is_base_of<WithParent>::value); // Ok as expected since WithParent inherits from T
static_assert(template_parameter_is_base_of<WoutParent>::value); // Error as expected since WithParent doesn't inherit from T
我失败的尝试
我尝试实现 template_parameter_is_base_of
:
struct Dummy {};
template<template<typename> class TemplateClass>
struct template_parameter_is_base_of
{
static constexpr bool value = std::is_base_of_v<Dummy, TemplateClass<Dummy>>;
};
...在这种情况下有效:
template<typename T>
struct A : T {
void work() { /* Irrelevant implementation */ }
};
static_assert(template_parameter_is_base_of<A>::value); // Passes because A inherits from its template parameter. Nice!
... 但是如果类模板有一个带有 override
的方法,它就会失败说明符:
template<typename T>
struct B : T {
void work() override { /* Irrelevant implementation */ }
};
static_assert(template_parameter_is_base_of<B>::value); // Fails, but I want it to pass because B inherits from its template parameter.
这就是我现在的想法
我想我已经用 Dummy
把自己逼到了一个角落上面使用的方法,因为 TemplateClass<Dummy>
的类模板实例化在 std::is_base_of_v
内如果 TemplateClass
将始终失败包含任何带有 override
的方法说明符。
但是,我认为实现 template_parameter_is_base_of
应该是可能的,因为编译器应该在编译时知道类模板是否继承自其模板参数。也许我错了。
最后的问题
是否可以实现 template_parameter_is_base_of
从 C++17 开始?如果是,那该怎么做?
最佳答案
However, I think that implementing
template_parameter_is_base_of
should be possible because a compiler should know at compile-time whether a template class inherits from its template parameter or not.
模板本质上是一种参数化工具,用于制造某些 C++ 结构:类、函数或变量。模板本身还不是它要制作的东西。类模板不继承任何东西,因为它还不是类。所以问题本身不是一个功能性问题。
与此相结合的是存在显式/部分模板特化这一事实。即使基类模板确实继承了它的第一个模板参数,也不能保证任何事情。你仍然不知道是否有任何特定的 WithParent<T>
模板的实例化实际上将使用基本模板。用户可以轻松地专门化 WithParent
对于特定类型,甚至对整个类型系列采用部分特化。
你要的不是C++能支持的。如果您试图验证某事或防止某些滥用或其他任何事情,您将不得不以另一种方式进行。
关于c++ - 在编译时检查未实例化的类模板是否继承自其第一个模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58467917/