相互依赖的类模板和std :: is_base_of专业化 [英] Interdependent class template and std::is_base_of specialization
问题描述
我对以下情况感到困惑,在以下情况下,我在 is_base_of
上启用了专业化.
I am mildy confused by the following situation where I have a specialization enabled on is_base_of
.
is_base_of
需要所检查类型的完整定义才可用.但是,正被检查的基本类型的成员正在使用正在被特殊化的类型-因此,两者都需要在另一个类型之前进行定义,并且我无法转发声明继承关系.
is_base_of
requires the full definition of the type that is being checked to be available. However, the type that is being specialized is being used as a member of the type who's base is being checked - so both need to be defined before the other, and I cannot forward declare the inheritance relationship.
令人困惑的是,如果我改为标记基础并在现有的此标记上启用,那么它将起作用.为了使它正常工作,必须在此时知道继承关系.那么为什么在没有完整定义的情况下 is_base_of
不起作用?
What is confusing is that if I instead tag the base and enable on this tag existing, it works. Surely for this to work, the inheritance relationship must be known at this point. so why doesn't is_base_of
work without the full definition being available?
#define OPTION 2 // OPTION 2 : broken, OPTION 1 : works
#include <iostream>
#include <type_traits>
using namespace std;
template <typename T,typename Enable=void>
struct child;
template <typename T>
struct base
{
typedef T type;
#if OPTION ==1
struct base_tag{};
#endif
};
#if OPTION ==2
template <typename T>
struct child < T, typename std::enable_if < std::is_base_of< base<typename T::type>, T>::value>::type>
{
const char* value = "specialization";
};
#else
template <typename T>
struct child < T, std::void_t<typename T::base_tag> >
{
const char* value = "specialization";
};
#endif
template <typename T>
struct dervived : base<T>
{
child<dervived> child_;
typedef T type;
};
int main() {
std::cout << dervived<int>().child_.value << std::endl;
return 0;
}
推荐答案
std :: is_base_of
需要完整的类型.情况并非如此
std::is_base_of
requires complete type. which is not the case in
template <typename T>
struct derived : base<T>
{
child<derived> child_; // derived<T> not yet complete here.
typedef T type;
};
对于 T :: base_tag
,IIRC(我认为 child< derived>
的POI从 struct导出
之前的位置移动到当前位置类), T
不需要完整,只需访问其中的一部分即可.
For T::base_tag
, IIRC (I think POI of child<derived>
move from before struct derived
to current location in the class), T
doesn't need to be complete, and only visited part of it is visible.
因此 derived :: type
将不可见.(但 derived :: base :: type
将会是).
So derived::type
would not be visible. (but derived::base::type
would be).
这篇关于相互依赖的类模板和std :: is_base_of专业化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!