В @David проблема связана с тем, что Face
является неполным, потому что оно входит в Base
до завершения определения Face
.
Однако решение, на которое ссылается @Davidнемного стар и пропускает некоторые уловки, которыми мы можем воспользоваться.А именно, @ms показывает нам, что функции static constexpr
хороши - и также основаны на моих собственных экспериментах - и нам действительно нужно иметь дело только с этим конкретным случаем static constexpr
переменных и, возможно, типов, к которым обращаются из Derived
.
Следующий ( живой пример ) показывает, как решить эту проблему, сохраняя каждый класс в своем собственном h-файле, делая его несколько чище:
#include <iostream>
// Begin: h-file of Base
template<class Drvd>
class ConstValue;
template<class Drvd>
class Base
{
public:
static constexpr bool val = ConstValue<Drvd>::val;
};
// End: h-file of Base
// Begin: h-file of Derived
class Derived;
template<>
class ConstValue<Derived>
{
public:
static constexpr bool val = true;
};
class Derived : public Base<Derived>
{
friend class Base<Derived>;
private:
static constexpr bool val = true; // optional
};
// End: h-file of Derived
// Main
int main()
{
std::cout << Derived::Base::val << std::endl;
}
Общая идея заключается в том, что для каждого constexpr
, к которому Base
необходим доступ из Derived
, мы можем создать отдельный класс, который инкапсулирует переменные, и затем перегрузить класс для каждого Derived
, который использует Base
.