2つの一般的に予期しない(異なる)型の2つの整数を比較する完全型保証型と最も柔軟な(constexpr
の点で)方法は何ですか?ここで任意の型の整数の比較
12
A
答えて
12
はアイデアです:ちょうど比較し、両方のタイプが符号なしの場合は
:私たちは、「通常の算術変換」を使用する必要があります。
両方の型が署名されている場合は、単に比較するだけです。
署名の度合いが異なり署名付きの値が負の場合は完了です。
実際の作業は、両方の値が負ではなく、符号が異なる場合に適用されます。符号なしの値が符号付きの型の最大符号付きの値より大きい場合、処理は完了です。それ以外の場合、符号なしの値は値を変更せずに符号付きの型に変換して比較することができます。
ここでの試みです:
#include <type_traits>
#include <limits>
template <bool SameSignedness> struct IntComparerImpl;
template <typename T, typename U>
constexpr bool IntCompare(T x, U y)
{
return IntComparerImpl<std::is_signed<T>::value ==
std::is_signed<U>::value>::compare(x, y);
}
// same signedness case:
template <> struct IntComparerImpl<true>
{
template<typename T, typename U>
static constexpr bool compare(T t, U u)
{
return t < u;
}
};
// different signedness case:
template <> struct IntComparerImpl<false>
{
// I1 is signed, I2 is unsigned
template <typename I1, typename I2>
static constexpr typename std::enable_if<std::is_signed<I1>::value, bool>::type
compare(I1 x, I2 y)
{
return x < 0
|| y > std::numeric_limits<I1>::max()
|| x < static_cast<I1>(y);
}
// I1 is unsigned, I2 is signed
template <typename I1, typename I2>
static typename std::enable_if<std::is_signed<I2>::value, bool>::type
compare(I1 x, I2 y)
{
return !(y < 0)
|| !(x > std::numeric_limits<I2>::max())
|| static_cast<I2>(y) < x;
}
};
1
My own solutionは(N3485.pdf§5に基づいて)これです:
#include <type_traits>
#include <limits>
#include <utility>
#include <cstdint>
#include <cstdlib>
template< typename L, typename R >
inline constexpr
typename std::enable_if< (std::is_signed<L>::value && !std::is_signed<R>::value), bool >::type
less(L const & lhs, R const & rhs)
{
static_assert(std::is_integral<L>::value,
"lhs value must be of integral type");
static_assert(std::is_integral<R>::value,
"rhs value must be of integral type");
using T = typename std::common_type< L, R >::type;
return (lhs < static_cast<L>(0)) || (static_cast< T const & >(lhs) < static_cast< T const & >(rhs));
}
template< typename L, typename R >
inline constexpr
typename std::enable_if< (!std::is_signed<L>::value && std::is_signed<R>::value), bool >::type
less(L const & lhs, R const & rhs)
{
static_assert(std::is_integral<L>::value,
"lhs value must be of integral type");
static_assert(std::is_integral<R>::value,
"rhs value must be of integral type");
using T = typename std::common_type< L, R >::type;
return !(rhs < static_cast<R>(0)) && (static_cast< T const & >(lhs) < static_cast< T const & >(rhs));
}
template< typename L, typename R >
inline constexpr
typename std::enable_if< (std::is_signed<L>::value == std::is_signed<R>::value), bool >::type
less(L const & lhs, R const & rhs)
{
static_assert(std::is_integral<L>::value,
"lhs value must be of integral type");
static_assert(std::is_integral<R>::value,
"rhs value must be of integral type");
return lhs < rhs;
}
namespace
{
static_assert(less(1, 2), "0");
static_assert(less(-1, std::numeric_limits<std::uintmax_t>::max()), "1");
static_assert(less< std::int8_t, std::uintmax_t >(-1, std::numeric_limits<std::uintmax_t>::max()), "2");
static_assert(less< std::intmax_t, std::uint8_t >(-1, std::numeric_limits<std::uint8_t>::max()), "3");
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-compare"
static_assert(!(-1 < std::numeric_limits< unsigned long >::max()), "4");
#pragma GCC diagnostic pop
static_assert(less(-1, std::numeric_limits< unsigned long >::max()), "5");
}
int main()
{
return EXIT_SUCCESS;
}
関連する問題
- 1. boost ::任意の比較値ですか?
- 2. Pythonで任意のデータ型の任意の2つのオブジェクトを比較します。
- 3. if文の比較整数
- 4. ポインタと整数の比較?
- 5. Delphi - NXライブラリの任意の長整数型?
- 6. 比較整数オブジェクト
- 7. Adaの任意の長さ整数
- 8. Cの整数へのポインタを比較
- 9. ポインタと整数の警告比較
- 10. ブール値と整数の比較
- 11. Scalaの数値型との比較?
- 12. 任意の型を返すPostgreSQL関数
- 13. 型パラメータvs任意のスカラー
- 14. PreparedStatementのBLOB型の比較
- 15. Pythonのデータ型の比較
- 16. 比較プリミティブ型
- 17. ハスケルでの型比較
- 18. C#オブジェクト型の比較
- 19. 整数と比較するバイト
- 20. NSPredicateを整数と比較する
- 21. xsl <xsl:testを使用した値比較のための任意のシンボルコード
- 22. SqlServer 2005(または一般に任意のRDBMS)のIN()とEXISTS()との比較
- 23. 任意の固定精度整数のプログラミング言語?
- 24. 変数をシェルの整数と比較しますか?
- 25. 整数のようなデータ型を使用した小数点/任意の算術の実装
- 26. 非テンプレートクラスの任意の型のC++メンバ変数
- 27. 整数にNSDateComponentsの比較(または整数にNSDateComponentsを変換)
- 28. コンソールからのC++入力、整数の比較
- 29. システムレベルでの整数と文字列の比較
- 30. 動的Javaの整数オーバーフローチェックとパフォーマンスの比較
はい^ –
私にコードレビューのためのより良いフィットだ - あなたの場合このための単体テストを作成し、予想外の動作を起こした場合、これは適切な場所になります。 –
['std :: common_type'](http://en.cppreference.com/w/cpp/types/common_type)を参照してください。それは比較の前に両側をキャストできる型を与えます。 – cHao