I have the following example code using virtual constexpr
from C++20 which does not compile:
enum legCount {
APODA = 0,
BIPEDAL = 2,
QUADRUPEDAL = 4,
};
class Animal {
public:
constexpr virtual legCount getLegCount() = 0;
};
class Tiger : public Animal {
public:
constexpr legCount getLegCount() { return QUADRUPEDAL; }
void manipulateLegsArray() {
unsigned char arr[getLegCount()];
}
};
This code compiles with Clang however MSVC complains that getLegCount
in unsigned char arr[getLegCount()];
does not evaluate to a constant expression (failure was caused by a read of a variable outside its lifetime). Is MSVC correct here and if so why is this?
Further, how can I mimic this functionality in a conformant way? I would like to have an abstract base class where all derived classes must implement the function and the function must be a constexpr.
Exact compiler error message as follow:
D:\Projects\temp\demo\main.cpp(17,32): error C2131: expression did not evaluate to a constant [D:\Projects\temp\out\demo\demo.vcxproj]
D:\Projects\temp\demo\main.cpp(17,21): message : failure was caused by a read of a variable outside its lifetime [D:\Projects\temp\out\demo\demo.vcxproj]
D:\Projects\temp\demo\main.cpp(17,21): message : see usage of 'this' [D:\Projects\temp\out\demo\demo.vcxproj]
manipulateLegsArray
function can be called at runtime by another class that inherits from your class, so getLegCount()
must be resolved at runtime, your array now becomes a variable length array, which MSVC doesn't support, it is only supported by clang/gcc.
you could enforce the derived class to implement something that is constexpr using CRTP.
enum legCount {
APODA = 0,
BIPEDAL = 2,
QUADRUPEDAL = 4,
};
template< typename T>
class Animal {
public:
static constexpr legCount getLegCount()
{
return T::legCount_v;
}
};
class Tiger : public Animal<Tiger> {
public:
constexpr static legCount legCount_v = QUADRUPEDAL;
void manipulateLegsArray() {
unsigned char arr[getLegCount()];
}
};
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