I need access to a static constexpr
and one solution I put together works with gcc (live example) but not with vc++ (live example).
The code is as follows:
template<class Drvd>
class Base
{
public:
static constexpr bool val = Drvd::val;
};
class Derived : public Base<Derived>
{
friend class Base;
private:
static constexpr bool val = true;
};
int main()
{
std::cout << Derived::Base::val << std::endl;
}
So it is a bug with vc++, but anyone has an idea on how to achieve val
defined in Base
as the value of val
in Drvd
in a different way that vc++ won't complain about?
Edit:
Note that the result is the same with the variant: friend class Base<Derived>;
instead of friend class Base;
Per @David, the problem has to do with Face
being incomplete, because it goes into Base
before finishing the definition of Face
.
However, the solution linked to by @David is a bit old and misses some tricks of which we can take advantage. Namely, @m.s. shows us that static constexpr
functions are fine - and also based on my own experimentation - and we really only need to deal with this particular case of static constexpr
variables, and perhaps types accessed from Derived
.
The following (live example) shows how to solve this problem, while keeping each class encapsulated to it's own h-file, making it somewhat cleaner:
#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;
}
The general idea is that for each constexpr
that Base
needs to access from Derived
, we can create a single class that encapsulate the variables, and then overload the class for each Derived
that uses Base
.