I'm confused about what I read about mixing virtual
and constexpr
for member functions.
According to:
up to C++17 included, it should not be possible to mix constexpr
and virtual
(standard is quoted in above links)
Yet I designed this straightfoward example:
#include <cstddef>
struct SizedObject {
virtual size_t GetSize() const = 0;
};
struct DynSizedObject : public SizedObject {
size_t s;
size_t GetSize() const override final { return s; }
};
struct StatSizedObject : public SizedObject {
const size_t s;
constexpr size_t GetSize() const override final { return s; }
constexpr explicit StatSizedObject(const size_t i) : s(i) {}
};
int main(int argc, char** argv) {
constexpr StatSizedObject SS(42);
DynSizedObject DS;
DS.s = argc + 2;
SizedObject const * p;
if (argc > 3) {
p = &SS;
} else {
p = &DS;
}
return p->GetSize();
}
I'm designing a hierarchy of objects with a size property that can be retrieved through the GetSize
member function, which I make virtual
. Now one of the concrete class can be instantiated with a compile-time size, and I make its GetSize
override constexpr
. Then my toy example trick the compiler in not knowing, at compile-time, which object will call GetSize
. In the Live I'm surprised to see that gcc accept the code. clang reject it, seemingly consistant with the standard, while msvc do as clang but also claim that the constexpr
version cannot result in a constant expression, which seems incorrect to me.
Thus my understanding would be that all compiler should behave like clang (but don't): is it correct? In this case, is it a gcc "bug" that it is accepting this construct? subsidiary question: why does msvc issue the cannot result in a constant expression error?
Beyond an academic interest, my purpose is to know if I may use some compile-time optimisation technics in relation with dynamic polymorphism (up to C++17, I know that, from C++20, some designs are possible).