Использование спецификатора вложенного имени в CRTP - PullRequest
0 голосов
/ 14 сентября 2018

Я использую 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_q наряду с impl_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> {
};

1 Ответ

0 голосов
/ 14 сентября 2018

impl_t является неполным типом в base. Вы можете решить эту проблему либо с помощью другого параметра шаблона, либо с помощью метода черт типа:

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 становится полным типом.

...