相互依赖的类模板和std :: is_base_of专业化 [英] Interdependent class template and std::is_base_of specialization

查看:55
本文介绍了相互依赖的类模板和std :: is_base_of专业化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对以下情况感到困惑,在以下情况下,我在 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆