Могут ли виртуальные функции, такие как X::f() в следующем коде
struct X
{
constexpr virtual int f() const
{
return 0;
}
};
be constexpr?
Ответ 1
Этот ответ больше не является правильным с С++ 20.
Нет. Из [dcl.constexpr]/3 (7.1.5, "Спецификатор constexpr "):
Определение функции constexpr должно удовлетворять следующим требованиям:
- это не должно быть виртуальным
Ответ 2
До С++ 17 функции virtual не могли быть объявлены constexpr. Общая причина в том, что в коде constexpr все может произойти во время компиляции. Так что в действительности нет особого смысла иметь функцию, которая берет ссылку на базовый класс и вызывает для него функции virtual; вы также можете сделать его функцией template и передать реальный тип, поскольку вы знаете реальный тип.
Конечно, это мышление не работает, так как код constexpr становится более сложным, или если вы хотите разделить интерфейсы между кодом компиляции и временем выполнения. В обоих случаях потерять трек оригинального типа легко. Это также позволило бы std::error_code быть больше constexpr -friendly.
Кроме того, тот факт, что С++ 20 позволит нам выполнять (ограниченное) динамическое размещение объектов, означает, что очень легко потерять след оригинального типа. Теперь вы можете создать vector<Base*> в коде constexpr, вставить в него несколько экземпляров класса Derived и передать его функции constexpr для работы.