可変引数のstd ::分std::common_type
で実装良い考えではありません。
署名されていないタイプと署名されたタイプを比較するとどうなりますか?あなたは、署名されたものが署名されていないと思っていますか?符号付き整数を符号なし整数に変換すると、非常に大きな正の値にラップする可能性があります。符号なし整数を符号付き整数に変換すると、オーバーフローするリスクがあります。
std::common_type
との比較を再帰的に実行すると、シーケンスのstd::common_type
は、隣接する2つのペアの間で同じstd::common_type
ではない場合があります。例えば
、
auto res = variadic_min(1, -211, 3, -63, 89u);
1, -211, 3, -63, 89u
のstd::common_type
がunsigned int
しかし
1, -211
のstd::common_type
がint
ですので、あなたがそれらを比較するとき、あなたは-211
が最小として返されますです。 -211, 3
と、また-211, -63
を比較すると同じことが言えます。しかし、-211 89u
を比較すると、std::common_type
はunsigned int
なので、-211
は4294967085になります。したがって、89u
は最小値です。もちろん、最小値でも最大値でもないので、ばかげています。整数昇進の犠牲者に過ぎない。あなたはすべての種類の間で均一にcommon_type
を使用したい場合は
は、その後、あなたはこのような何かがあります
template<class T, class U>
std::common_type_t<T, U>
variadic_min(const T& t, const U& u)
{
if (t < u)
std::cout << t << " less than " << u << std::endl;
else
std::cout << u << " less than " << t << std::endl;
return t < u ? t : u;
}
template<class First, class Second, class... Rest>
std::common_type_t<First, Second, Rest...>
variadic_min(const First& f, const Second& s, const Rest& ...t)
{
using ret_t = std::common_type_t<First, Second, Rest...>;
return variadic_min(variadic_min(static_cast<ret_t>(f), static_cast<ret_t>(s)), static_cast<ret_t>(t)...);
}
そして少なくともあなたは不可欠なプロモーションによって被害を受けていないが、すべてのタイプがunsigned int
に変換されるので、出力は少なくとも予測可能です。すべての負の数が正の大きなものになるだろう:
出力:
1 less than 4294967085
1 less than 3
1 less than 4294967233
1 less than 89
Res: 1
は、最終的にはより良いアプローチは、未署名のために目を光らせてするかもしれない/比較を締結し、その場合には、特別な何かをします。例えば。最初に符号付きの値を0にチェックし、それよりも小さい場合は、符号付きの値を大きな正の値にキャストするのではなく、その値を返します。
値はここでretvalにコピーされますが、そうではありませんか? –
@AdamHunyadi:はい、そうです。それはやむを得ないことです。 – Cornstalks
'' const ref''型を値型に変換するには 'common_type :: type(等)'を使います。 –