【问题标题】:CRTP + Traits class : "no type named..."CRTP + Traits 类:“没有类型命名...”
【发布时间】:2012-08-03 12:39:20
【问题描述】:

我尝试使用模板类实现 CRTP,但以下示例代码出错:

#include <iostream>

template<class T> class Traits
{
    public:
        typedef typename T::type type; // <- Error
                                       // : "no type named 'type' in 'class MyClass<double, 3u, 3u>'
        static const unsigned int m_const = T::m_const;
        static const unsigned int n_const = T::n_const;
        static const unsigned int size_const = T::m_const*T::n_const;
};

template<class T0> class Crtp
{
    public:
        typedef typename Traits<T0>::type crtp_type;
        static const unsigned int size = Traits<T0>::size_const; // <- This is OK
};

template<typename TYPE, unsigned int M, unsigned int N>
class MyClass : public Crtp< MyClass<TYPE, M, N> >
{
    public:
        typedef TYPE type;
        static const unsigned int m_const = M;
        static const unsigned int n_const = N;
};

int main()
{
    MyClass<double, 3, 3> x;
    std::cout<<x.size<<std::endl;
    return 0;
}

我不明白是什么导致了这个问题,也不知道如何解决。

事实上,我的目标是 CRTP 类必须知道派生类的模板参数,而无需将它们作为 CRTP 类的模板参数传递。

你有什么想法如何实现这个吗?

编辑(与第一个有关):我的 CRTP 类必须能够处理具有不同数量模板参数的派生类

【问题讨论】:

    标签: c++ templates crtp typetraits


    【解决方案1】:

    问题是MyClass 在它自己的基类列表中不完整,您在其中实例化Crtp&lt;MyClass&gt;。但是实例化Crtp&lt;MyClass&lt;...&gt;&gt; 需要实例化Traits&lt;MyClass&lt;...&gt;&gt;,然后需要实例化MyClass&lt;...&gt;::type,这是不可能的,因为它不完整。你有一个循环依赖。

    其实我的目标是CRTP类必须知道派生类的模板参数

    这可以使用部分特化和模板模板参数来完成,如下所示:

    #include <iostream>
    
    template<typename T> class Crtp;
    
    template<template<typename, unsigned, unsigned> class T, typename U, unsigned M, unsigned N>
    class Crtp< T<U, M, N> >
    {
        public:
            typedef U crtp_type;
            static const unsigned int size = M * N;
    };
    
    template<typename TYPE, unsigned int M, unsigned int N>
    class MyClass : public Crtp< MyClass<TYPE, M, N> >
    {
    };
    
    int main()
    {
        MyClass<double, 3, 3> x;
        std::cout<<x.size<<std::endl;
        return 0;
    }
    

    【讨论】:

    • 如果您能解释一下部分专业化如何解决问题,那就太好了?
    • 我编辑了我的帖子,因为理想情况下我的 crtp 类应该能够处理具有不同数量参数的派生类。
    • @Mr.Anubis,它避免了循环依赖,而是部分特化匹配模板的形式并将MyClass&lt;T, M, N&gt;“挑选”到模板MyClass及其参数T中, MN,因此 ti 可以引用这些参数。
    • @Vincent,这可以通过额外的专业化来完成。也许不理想,但它具有编译和工作的优势,而您的原始版本没有;)
    • @JonathanWakely arhhh 我刚刚注意到您删除了特征类并直接执行此操作:)
    猜你喜欢
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 2023-04-07
    • 2021-02-03
    相关资源
    最近更新 更多