【问题标题】:Resolving CRTP initialization order解析 CRTP 初始化顺序
【发布时间】:2019-10-17 13:40:58
【问题描述】:

我有一些 CRTP 依赖项,我不确定如何解决。理想情况下,我想在基类中放入尽可能多的东西,比如函数,所以我不必为每个继承它们的类重新定义它们。这似乎会导致初始化顺序出现问题,其中result_type 取决于尚未初始化的类型。这是一个例子:https://godbolt.org/z/YpfcPB

这里是代码:

template<typename T>
struct CRTP_Derived;

template<typename Derived>
struct CRTP
{
    using result_type = typename Derived::result_type;

};

template<typename T>
struct CRTP_Derived : public CRTP<CRTP_Derived<T>>
{
    using result_type = T;
};

int main()
{
    CRTP_Derived<int> a;
    return 0;
}

【问题讨论】:

  • “初始化”在这里不是正确的词。这个问题与一个类类型何时被认为是完整的有关。
  • @aschepler 然后实例化?如果我可以定义顺序,我就不会有问题。这就是 traits 的真正作用——它将result_type 推迟到以后。

标签: c++ templates crtp


【解决方案1】:

我还为此类问题使用了单独的特征类型。如果您将特征作为第二个模板参数,而不是要求用户专门使用单独的模板,则可以稍微减少所需的样板:

template<typename Derived, typename Traits>
struct CRTP
{
    using result_type = typename Traits::result_type;
};

template<typename T>
struct CRTP_Derived_Traits
{
    using result_type = T;
};

template<typename T>
struct CRTP_Derived : public CRTP<CRTP_Derived<T>, CRTP_Derived_Traits<T>>
{
};

int main()
{
    CRTP_Derived<int> a;
    return 0;
}

【讨论】:

    【解决方案2】:

    我发现的一种解决方法是在单独的类中取出 typedef,但我仍然很高兴看到其他解决方案。 https://godbolt.org/z/a7NCE2

    template<typename T>
    struct CRTP_Derived;
    
    template<typename Derived>
    struct traits;
    
    template<typename T>
    struct traits<CRTP_Derived<T>>
    {
        using result_type = T;
    };
    
    template<typename Derived>
    struct CRTP
    {
        using result_type = typename traits<Derived>::result_type;
    };
    
    template<typename T>
    struct CRTP_Derived : public CRTP<CRTP_Derived<T>>
    {
        using result_type = T;
    };
    
    int main()
    {
        CRTP_Derived<int> a;
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-17
      • 1970-01-01
      • 2011-10-20
      • 1970-01-01
      • 1970-01-01
      • 2015-08-16
      相关资源
      最近更新 更多