相互依赖的类模板和std :: is_base_of专业化

时间:2018-06-21 12:22:44

标签: c++

我为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;
}

DEMO

1 个答案:

答案 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会是)。