I have a class that can inherit from an empty struct or from a struct with some members, depending on a bool. Using that same bool, I am adding an if constexpr block to access the members of the base class, but I am getting a compiler error
struct A{};
struct B{};
struct C{};
template <typename J0, typename J1>
struct HasFriction {
constexpr static bool value = false;
};
template <> struct HasFriction<A,B> {
constexpr static bool value = true;
};
template <bool> struct Friction { };
template <> struct Friction<true> { int value = 4; };
template <typename J0, typename J1>
struct MyStruct : public Friction<HasFriction<J0, J1>::value> {};
int main()
{
if constexpr (HasFriction<A, C>::value) {
MyStruct<A,C> f;
return f.value;
} else {
MyStruct<A,C> no_f;
return 0;
}
}
Why is this not working, and how should I fix it?
Why is this not working and how should I fix it?
In order to work if constexpr (i.e. discard the false statement at compile time), you need to make it template depended.
From cppreference.com, under the if constexpr section:
Outside a template, a discarded statement is fully checked.
if constexpris not a substitute for the#ifpreprocessing directive:void f() { if constexpr(false) { int i = 0; int *p = i; // Error even though in discarded statement } }
Therefore, the fix is to wrap the statement into a template function, as follows:
template<typename T1, typename T2> auto func()
{
if constexpr (HasFriction<T1, T2>::value) {
MyStruct<A, C> f;
return f.value;
}
else {
MyStruct<A, C> no_f;
return 0;
}
}
Now in main()
func<A, B>();
See a demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With