のドキュメントにstd::numeric_limits<T>
は、非基本型に特化すべきではないと書かれています。数値のようなユーザー定義型はどうですか? T
数値を表し、数値演算子をオーバーロードする独自の型を定義し、によって表される情報が意味をなす場合、その型numeric_limits
に特化すると何かが壊れますか?numeric_limits
3 に答える
簡潔な答え:
どうぞ、何も悪いことは起こりません。
長い答え:
C++ 標準は::std
、C++11 17.6.4.2.1 の名前空間を広範囲に保護しますが、具体的には段落 1 と 2 でケースを許可します。
特に指定がない限り、名前空間 std または名前空間 std 内の名前空間に宣言または定義を追加する場合、C++ プログラムの動作は未定義です。プログラムは、宣言がユーザー定義型に依存し、特殊化が元のテンプレートの標準ライブラリ要件を満たし、明示的に禁止されていない場合にのみ、標準ライブラリ テンプレートのテンプレート特殊化を名前空間 std に追加できます。
[...] プログラムは、宣言がユーザー定義型の名前に依存し、インスタンス化が元のテンプレートの標準ライブラリ要件を満たす場合にのみ、標準ライブラリで定義されたテンプレートを明示的にインスタンス化できます。
古い C++03 では、17.4.3.1/1 に同様の定義があります。
特に指定がない限り、C++ プログラムが名前空間 std または名前空間 std 内の名前空間に宣言または定義を追加することは未定義です。プログラムは、標準ライブラリ テンプレートのテンプレートの特殊化を名前空間 std に追加できます。このような標準ライブラリ テンプレートの特殊化 (完全または部分的) は、宣言が外部リンケージのユーザー定義名に依存しない限り、および特殊化が元のテンプレートの標準ライブラリ要件を満たさない限り、未定義の動作をもたらします。
この基本的な足がかりを乗り越えた後、あなたはすでに指摘しましたが、C++03 18.2.1/4 では::std::numeric_limits
特定の型の特殊化が禁止されています。
複合体 (26.2.2) などの非基本的な標準型には、特殊化があってはなりません。
最新の C++11 18.3.2.1/4 では、少し異なる表現があります。
(26.4.2)などの非算術標準型には、
complex<T>
特殊化があってはなりません。
ただし、これらの定式化は両方とも、非標準型の特殊化を許可しますT
。つまり、自分で定義したためです (@BoPersson がコメントで既に指摘しているように)。
注意事項
C++11 18.3.2.3/1 は、特殊化にすべてのメンバーがあることを確認する必要があることを示唆しています (ただし、必須ではありません)。
また、C++11 18.3.2.3/2 が専門分野に違反していないことを確認したい場合もあります。
cv 修飾された型 cv T での numeric_limits の特殊化の各メンバーの値は、非修飾型 T での特殊化の対応するメンバーの値と等しくなければなりません。
つまり、 に特化したい場合は 、 、 にも特化するT
必要がT const
ありT volatile
ますT const volatile
。
ユーザー定義型に対して std::numeric_limits を特殊化することはできません。ユーザー定義型は算術型ではありません。C++ 標準には明確に書かれています。
1 numeric_limits クラス テンプレートは、算術型の実装表現のさまざまなプロパティに関する情報を C++ プログラムに提供します。
そして例えば
4複合体(26.4.2)などの非算術標準型は、特殊化を持たないものとします。