I came up with this class:
class Point
{
public:
int X, Y;
mutable int Z;
constexpr Point(int x, int y) :X (x), Y(y), Z(0)
{ }
constexpr int GetX() const
{
// Z++; // Wont compile, but following expression is valid!
return X+Z;
}
int GetY() const
{
Z++;
return Y;
}
void FoolConst() const
{
Z++;
}
};
And here is usage:
template<int S>
void foo()
{
std::cout << S << std::endl;
}
int main()
{
constexpr Point pt(10, 20);
pt.FoolConst();
char arr[pt.GetX()]; // Both compile, but GCC is using extended `new`
foo<pt.GetX()>(); // GCC fails, VC compiles
std::cout << sizeof(arr); // 10 (MSVC), 11 (GCC)
std::cout << pt.GetX(); // 11 (MSVC), 11(GCC)
}
Questions:
- Why
GetX
is compiling well withX+Z
as return expression (Z is not constexpr). - How can I call
FoolConst
andGetY
methods out ofconstexpr
object (pt
) ? - The behaviour of
GetX
inmain
is different in compilers. MSVC compiles fine with aint
as template argument, while GCC (IdeOne) won't compile it.
For one compiler constexpr GetX
is truly constexpr
, but for other it is not if X+Z
is involved. If I remove +Z
and simply return X
GCC is okay.
My question is very basic: If object is constexpr
how can it call a non-constexpr method?