テンプレート クラスでの静的メンバーの初期化の複雑さ
C での静的メンバーの初期化は広く使用されている手法ですが、次のような処理を行うと複雑になる可能性があります。テンプレート化されたクラス。テンプレート化されていないクラスでは、ネストされたヘルパー構造体を初期化に使用できますが、囲んでいるクラスがテンプレート化されている場合、このアプローチは不十分です。
次の単純化された例を考えてみましょう:
struct A
{
static std::string mA;
static InitHelper mInit;
static const std::string& getA() { return mA; }
};
std::string A::mA;
A::InitHelper A::mInit;
template
struct B
{
static std::string mB;
static InitHelper mInit;
static const std::string& getB() { return mB; }
static InitHelper& getHelper() { return mInit; }
};
template
std::string B::mB;
template
typename B::InitHelper B::mInit;
int main()
{
std::cout ::getB() ::getHelper(); // [2]
}
期待される動作:
[1] がコメント化されておらず、[2] がコメント化されている場合、B
実際の動作:
不一致の理由:
ISO/IEC C 2003 標準によれば、テンプレート メンバーは、その定義が必要なコンテキストで参照されると暗黙的にインスタンス化されます。存在する。ただし、静的データ メンバーの初期化 (および関連する副作用) は、静的データ メンバーが明示的に使用される場合にのみ発生します。これは、テンプレート メンバーがインスタンス化されていないテンプレート、または完全なインスタンス化を必要としない他のコンテキストでのみ参照される場合、その静的データ メンバーは初期化されないことを意味します。
この例では、B
Solution:
この標準では、明示的に特殊化されたクラス テンプレートの静的データ メンバーの定義には順序付けされた初期化が必要ですが、他のクラス テンプレートの静的データ メンバーには順序付けされていない初期化が必要です。一貫した初期化順序を確保するには、明示的な特殊化を使用する必要があります。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3