web-dev-qa-db-ja.com

仮想関数をconstexprにすることはできますか?

次のコードでX::f()のような仮想関数を使用できますか

struct X 
{
    constexpr virtual int f() const 
    {
        return 0;
    }
};

constexprになりますか?

15
Ralph Tandetzky

この回答はC++ 20以降正しくありません。

いいえ。[dcl.constexpr]/3から(7.1.5、 "constexpr指定子"):

constexpr関数の定義は、次の要件を満たす必要があります。

—それは仮想であってはならない

27
Kerrek SB

C++ 17までは、virtual関数をconstexprとして宣言できませんでした。一般的な理由は、constexprコードでは、すべてがコンパイル時に発生する可能性があるためです。したがって、基本クラスへの参照を受け取り、その上でvirtual関数を呼び出す関数を持つことにはあまり意味がありません。実数型を知っているので、それをtemplate関数にして、実数型を渡すこともできます。

もちろん、constexprコードがより複雑になるため、またはコンパイル時コードとランタイムコード間でインターフェイスを共有する場合、この考え方は実際には機能しません。どちらの場合も、元のタイプを見失うことは簡単です。また、std::error_codeをよりconstexprに適したものにすることもできます。

また、C++ 20でオブジェクトの(制限された)動的割り当てを実行できるという事実は、元のタイプを見失うことが非常に簡単であることを意味します。これで、constexprコードにvector<Base*>を作成し、それにいくつかのDerivedクラスインスタンスを挿入し、それをconstexpr関数に渡して操作することができます。

したがって、C++ 20 virtual関数をconstexpr として宣言できます。

6
Nicol Bolas