次のコードでX::f()
のような仮想関数を使用できますか
struct X
{
constexpr virtual int f() const
{
return 0;
}
};
constexpr
になりますか?
この回答はC++ 20以降正しくありません。
いいえ。[dcl.constexpr]/3から(7.1.5、 "constexpr
指定子"):
constexpr
関数の定義は、次の要件を満たす必要があります。—それは仮想であってはならない
C++ 17までは、virtual
関数をconstexpr
として宣言できませんでした。一般的な理由は、constexpr
コードでは、すべてがコンパイル時に発生する可能性があるためです。したがって、基本クラスへの参照を受け取り、その上でvirtual
関数を呼び出す関数を持つことにはあまり意味がありません。実数型を知っているので、それをtemplate
関数にして、実数型を渡すこともできます。
もちろん、constexpr
コードがより複雑になるため、またはコンパイル時コードとランタイムコード間でインターフェイスを共有する場合、この考え方は実際には機能しません。どちらの場合も、元のタイプを見失うことは簡単です。また、std::error_code
をよりconstexpr
に適したものにすることもできます。
また、C++ 20でオブジェクトの(制限された)動的割り当てを実行できるという事実は、元のタイプを見失うことが非常に簡単であることを意味します。これで、constexpr
コードにvector<Base*>
を作成し、それにいくつかのDerived
クラスインスタンスを挿入し、それをconstexpr
関数に渡して操作することができます。
したがって、C++ 20 virtual
関数をconstexpr
として宣言できます。