私は最近、効率性と安全性の理由から、特に多型ではないテンプレートクラスを設計していたC++ライブラリに取り組んでいました。後で私がこれを忘れずに、すべてを間違って壊すことを防ぐために、私は良い市民であり、その効果を静的な主張に加えると思った。テンプレートクラスがポリモーフィックでないことを確認しますか?
私が最初にこのような何か試してみました:
template <typename T> class VirtualVerboten {
...
static_assert(!std::is_polymorphic<VirtualVerboten>::value,
"This should not be polymorphic."); // Error!
};
私はVirtualVerboten
を使用している時に、それは不完全なタイプですが、これはコンパイルされませんが。これは、非テンプレートクラスだったら、私はちょうど右のタイプの後static_assert
を置くところ:
class NonTemplateVirtualVerboten {
...
}
static_assert(!std::is_polymorphic<NonTemplateVirtualVerboten>::value,
"This should not be polymorphic.");
をしかし、これはテンプレートクラスであることから、「テンプレートstatic_assert
」を作るの類似したアイデアは法的ではありません:私が思いついた
template <typename T> class VirtualVerboten {
...
};
template <typename T>
static_assert(!std::is_polymorphic<VirtualVerboten>::value,
"This should not be polymorphic."); // Error!
ソリューションは、おそらくテンプレートが(具体的には、コンストラクタ)インスタンス化されたとき、そこに静的アサーションを入れて使用されるVirtualVerboten
の内部メンバ関数を見つけることだった。
template <typename T> class VirtualVerboten {
VirtualVerboten();
};
template <typename T>
VirtualVerboten<T>::VirtualVerboten() {
static_assert(!std::is_polymorphic<VirtualVerboten>::value,
"This should not be polymorphic."); // Yay!
doSomeActualThingsAtRuntime();
}
この特定のコンストラクタが実際に呼び出され、インスタンス化されるということを除いて、これは機能します。これは、呼び出すことができるコンストラクタが複数ある場合に失敗します。
ここにこの静的アサーションを追加する「確実な方法」はありますか?なぜ元のコードがエラーを生成していたのか、そしてテンプレート静的アサーションを使用できない理由を理解しています。これは、「これを行う別の方法がありませんでしたか? 「あなたがしたことがうまくいかない理由はここにあります。
うう:
IMO、別のエレガントな方法は、次のような、&は同じ継承するユーティリティクラスを作成するのですか?コンストラクタ?どういうわけか、クラスをどこかに構築しなければなりません。あなたの静的な主張を押してください。 –
@SamVarshavchikそれは私がやったことです。おそらく私は質問を編集して、それをもっと明確にするべきです。 – templatetypedef
静的アサーションは2番目のフェーズでのみチェックされるように、型を依存関係にパッケージ化するだけで済みます。 –