我为is_base_of
启用了专业化功能而感到困惑。
is_base_of
要求提供正在检查的类型的完整定义。但是,正被检查的类型的成员正使用正在被专用化的类型-因此,必须先定义两者,然后才能转发声明继承关系。
令人困惑的是,如果我改为标记基础并在现有的此标记上启用,它将起作用。为了使它正常工作,必须在此时知道继承关系。那么为什么is_base_of
在没有完整定义的情况下不能工作?
#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;
}
答案 0 :(得分:1)
std::is_base_of
需要完整的类型。情况并非如此
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 derived
之前的位置移动到班级中的当前位置),T
不需要完整,并且只有其中一部分可以看到。
因此derived::type
将不可见。 (但derived::base::type
会是)。