【问题标题】:Using a nested name specifier in CRTP在 CRTP 中使用嵌套名称说明符
【发布时间】:2018-09-14 08:38:01
【问题描述】:

我正在使用 CRPT,需要访问派生类中定义的基类中的参数。它在成员函数中使用时起作用,但在(我猜的)编译时表达式中不起作用(定义类型时会出现问题)。下面的代码说明了这个问题:

#include <iostream>
#include <array>

template <typename impl_t>
struct base {
// no complaints
  void print () {
    std::cout << "Base, impl_t::i_q = " << impl_t::i_q << std::endl;
  }
// compiler error:
//                 clang++: no member named 'i_q' in 'deriv_t'
//                 g++:     incomplete type ‘deriv_t’ used in nested name specifier
  using vec_t = std::array<double, impl_t::i_q>;
};

struct deriv_t : public base<deriv_t> {
  static const std::size_t i_q = 1;
};

int main () {
  deriv_t d;
  d.print();
}

我只是想知道这里违反了哪些规则?我想出的解决方案是在模板中定义i_qimpl_t,但想知道是否有更整洁的方法来解决问题。

解决方案:

感谢 Evg,这是解决方案:

template <typename impl_t>
struct traits;

template <typename impl_t>
struct base_t {
  void print () {
    std::cout << "Base, impl_t::i_q = " << traits<impl_t>::i_q << std::endl;
  }
  using vec_t = std::array<double, traits<impl_t>::i_q>;
};

struct deriv_t;

template <>
struct traits<deriv_t> {
  static const std::size_t i_q = 1;
};
struct deriv_t : public base_t<deriv_t> {
};

【问题讨论】:

    标签: c++ templates crtp


    【解决方案1】:

    impl_tbase 中的不完整类型。您可以使用另一个模板参数或使用类型特征技术来解决问题:

    template<class>
    struct traits;
    
    template<>
    struct traits<deriv_t>
    {
        static constexpr std::size_t i_q = 1;
    };
    
    ...
    
    void print () {
        std::cout << "Base, i_q = " << traits<impl_t>::i_q << std::endl;
    }
    
    using vec_t = std::array<double, traits<impl_t>::i_q>;
    

    您在print() 中没有抱怨,因为在它的实例化点impl_t 变成了一个完整的类型。

    【讨论】:

    • 感谢您的回复,关于从哪里开始研究类型特征技术有什么建议吗?我在type_traits 库上打开了 cppreference 页面,有点害怕。
    • 1) Alexandrescu A. 现代 C++ 设计。应用了通用编程和设计模式。 2) Vandevoorde D. C++ 模板。完整指南。
    • @FChambers, &lt;type_traits&gt; 库本身并不是您所需要的。它包含现成的特征,但您需要自己编写。
    • 感谢示例代码,可以用来解决问题。我已经用解决方案修改了问题。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多