Can virtual functions like X::f()
in the following code
struct X
{
constexpr virtual int f() const
{
return 0;
}
};
be constexpr
?
Can virtual functions like X::f()
in the following code
struct X
{
constexpr virtual int f() const
{
return 0;
}
};
be constexpr
?
Up through C++17, virtual
functions could not be declared constexpr
. The general reason being that, in constexpr
code, everything happen can at compile time. So there really isn't much point to having a function which takes a reference to a base class and calls virtual
functions on it; you may as well make it a template
function and pass the real type, since you know the real type.
Of course, this thinking doesn't really work as constexpr
code becomes more complex, or if you want to share interfaces between compile-time and runtime code. In both cases, losing track of the original type is easy to do. It would also allow std::error_code
to be more constexpr
-friendly.
Also, the fact that C++20 will allow us to do (limited) dynamic allocation of objects means that it is very easy to lose track of the original type. You can now create a vector<Base*>
in constexpr
code, insert some Derived
class instances into it, and pass that to a constexpr
function to operate on.
const
reference to an empty base to allow array size to be a NTTP on the actual tag list was a relatively clean way to solve one of the issues, but introduced its own problems due to the lack of constexpr virtual
. Glad to see this'll be available soon! –
Heteronym This answer is no longer correct as of C++20.
No. From [dcl.constexpr]/3 (7.1.5, "The constexpr
specifier"):
The definition of a
constexpr
function shall satisfy the following requirements:— it shall not be virtual
gcc version 4.9.2 20141101 (Red Hat 4.9.2-1) (GCC)
it works –
Knowhow Up through C++17, virtual
functions could not be declared constexpr
. The general reason being that, in constexpr
code, everything happen can at compile time. So there really isn't much point to having a function which takes a reference to a base class and calls virtual
functions on it; you may as well make it a template
function and pass the real type, since you know the real type.
Of course, this thinking doesn't really work as constexpr
code becomes more complex, or if you want to share interfaces between compile-time and runtime code. In both cases, losing track of the original type is easy to do. It would also allow std::error_code
to be more constexpr
-friendly.
Also, the fact that C++20 will allow us to do (limited) dynamic allocation of objects means that it is very easy to lose track of the original type. You can now create a vector<Base*>
in constexpr
code, insert some Derived
class instances into it, and pass that to a constexpr
function to operate on.
const
reference to an empty base to allow array size to be a NTTP on the actual tag list was a relatively clean way to solve one of the issues, but introduced its own problems due to the lack of constexpr virtual
. Glad to see this'll be available soon! –
Heteronym Can virtual functions be constexpr?
Yes. Only since C++20, virtual functions can be constexpr
.
In C++20 and later, a constexpr function can be virtual, and a constructor can be defined as constexpr when the enclosing class has any virtual base classes.
© 2022 - 2025 — McMap. All rights reserved.
constexpr
purpose. – TismanX
. This would essentially require the language to specify "devirtualization rules". – Fleabagfinal
functions to be able to beconstexpr
. – Wormeaten