私は、次のコードスニペットを持っている:イニシャライザのリストはパラメータの順序によって変わってきますか?
#include <type_traits>
#include <limits>
#include <initializer_list>
#include <cassert>
template <typename F, typename... FIn>
auto min_on(F f, const FIn&... v) -> typename std::common_type<FIn...>::type
{
using rettype = typename std::common_type<FIn...>::type;
rettype result = std::numeric_limits<rettype>::max();
(void)std::initializer_list<int>{((f(v) < result) ? (result = static_cast<rettype>(v), 0) : 0)...};
return result;
}
int main()
{
auto mod2 = [](int a)
{
return a % 2;
};
assert(min_on(mod2, 2) == 2); // PASSES as it should
assert(min_on(mod2, 3) == 3); // PASSES as it should
assert(min_on(mod2, 2, 3) == 3); // PASSES but shouldn't - should be 2
assert(min_on(mod2, 2, 3) == 2); // FAILS but shouldn't - should be 2
}
テンプレート関数min_on
の背後にある考え方は、それが表現f(v)
の最小値を与えるように、それはそれv
に渡されたパラメータのリストからパラメータx
を返さなければならないことです。
私が観察している問題は、このコードに対し、上記のコードは失敗しますので、何とかstd::initializer_list
内部パラメータの順序が重要であるということです。
assert(min_on(mod2, 3, 2) == 2);
が動作します。ここで何が間違っているのでしょうか?
がが最高の入力と最高出力の両方を保存する方が効率的でしょう:あなたは
f
に不要な呼び出しを避けたいなら、または:だから、多分あなたの代わりに、最初の引数を必要とする可能性がありますfへの繰り返しの呼び出しを避けるためです。 –
完璧な答え!私はmore.Thanks多くを求めることができませんでしたBenjamin – Patryk
これは、オプションを返すか、空のリストに失敗する必要があります。あなたの提案は、コンパイル時に空で失敗します。これは良いことです。 modedtコストでは、回答の索引を追跡し、答えを見つけた後に値に戻すことで、結果の型を繰り返しコピーすることを避けることができます(高価になる可能性があります)が、かなり進歩しています。 – Yakk