【问题标题】:Interdependent class template and std::is_base_of specialization相互依赖的类模板和 std::is_base_of 特化
【发布时间】:2018-06-21 12:22:43
【问题描述】:

我对以下我在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

【问题讨论】:

  • 你应该把你的例子一分为二,因为它已经很难理解并且必须通读条件块并没有真正的帮助。
  • 我倾向于同意霍尔特的观点。如果您只保留选项 2,它将更具可读性。标签解决方法真的无关紧要。
  • 您可以将选项 2 缩减为:godbolt.org/g/Ncm6Ad,将选项 1 缩减为大致相同的长度。 slimbody 在这里不相关,您只想检查是否为 fatbody 选择了专业化。
  • 但问题是关于标签解决方法 - 所以并非无关紧要。标签变通方法要求被检查的类型是从提供标签的基础继承的。那么这不需要知道继承关系,因此为什么 is_base_of 在使用之前需要完整的定义。但是当继承并使用标签时,不会。
  • @AndyG:我认为这与void_tenable_if_t 无关,但is_base_ofT::tag 之间的类型支持不完整。

标签: c++


【解决方案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&lt;derived&gt;的POI从struct derived之前移动到班级中的当前位置),T不需要完整,只有访问过的部分可见.

所以derived::type 将不可见。 (但derived::base::type 会)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-12
    • 2011-01-25
    • 2013-03-26
    • 2013-05-29
    • 1970-01-01
    • 1970-01-01
    • 2022-07-08
    • 1970-01-01
    相关资源
    最近更新 更多