代码之家  ›  专栏  ›  技术社区  ›  Jonathan Boccara

CRTP:为什么获取派生类的嵌套类型和嵌套方法有区别?

  •  7
  • Jonathan Boccara  · 技术社区  · 6 年前

    CRTP模式中的基类可以访问派生类的成员函数,但不能访问派生类中的嵌套类型。

    为什么会有这种不同?

    为了说明这一点,请考虑以下代码:

    template<typename Derived>
    struct crtp_base
    {
        void crtp_method() { return static_cast<Derived&>(*this).method(); } // compiles
    
        using crtp_type = typename Derived::type; // doesn't compile
    };
    
    struct X : public crtp_base<X>
    {
        void method() {}
    
        using type = int;
    };
    
    int main()
    {
    
    }
    

    crtp_type 导致编译错误,而 crtp_method 编译得很好,尽管两者都试图访问 Derived 上课。解释差异的C++规范是什么?

    1 回复  |  直到 6 年前
        1
  •  8
  •   user7860670    6 年前

    这里的区别在于,方法的实例化只在您在 crtp_base 发生在 public crtp_base<X> where类型 X 仍然不完整。解决方法是使用类型特征:

    template<typename x_Target>
    struct Trait;
    
    template<typename Derived>
    struct crtp_base
    {
        void crtp_method() { return static_cast<Derived&>(*this).method(); }
    
        using crtp_type = typename Trait<Derived>::type;
    };
    
    struct X;
    
    template<>
    struct Trait<X>
    {
        using type = int;
    };
    
    struct X : public crtp_base<X>
    {
        void method() {}
    
        using type = Trait<X>::type;
    };