Here I have a simple CRTP case:
#include <cstddef>
#include <utility>
template <typename Impl>
class base
{
constexpr static size_t impl_num = Impl::num;
};
template <typename Impl>
class deriv : public base<deriv<Impl>>
{
friend class base<deriv<Impl>>;
constexpr static size_t num = Impl::num_in;
};
class actual_impl
{
public:
constexpr static size_t num_in = 10;
};
using my_type = deriv<actual_impl>;
int main()
{
my_type a{};
}
This snippet compiles fine but when I change the base class to:
#include <cstddef>
#include <utility>
template <typename Impl>
class base
{
constexpr static std::make_index_sequence<Impl::num> idx{};
};
template <typename Impl>
class deriv : public base<deriv<Impl>>
{
friend class base<deriv<Impl>>;
constexpr static size_t num = Impl::num_in;
};
class actual_impl
{
public:
constexpr static size_t num_in = 10;
};
using my_type = deriv<actual_impl>;
int main()
{
my_type a{};
}
Clang complains that error: no member named 'num' in 'deriv<actual_impl>'. I'm just confused why the first case works but not the second one, what's the fundamental difference between these two since it seems to me that in both cases Impl::num_in are used in base class.
In general, is it possible for base class to use typedefs or constexprs from Impl?