私はboost::adaptors::transformed
(map
としましょう)をboost::adaptors::filtered
(これをfilter
としましょう)にチェーンしようとしています。範囲を超えて「おそらく」(私の場合はstd::pair<bool, T>
)を返し、結果の一部のみを出力するfun
をマップします。私の最初の実装:boost :: adapters :: transformedに続いてboost :: adapters :: filtered関数が2回呼び出されました
define BOOST_RESULT_OF_USE_DECLTYPE // enable lambda arguments for Boost.Range
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/adaptor/transformed.hpp>
struct OnlyEven
{
typedef int argument_type;
typedef std::pair<bool, int> result_type;
result_type operator()(argument_type x) const
{
std::cout << "fun: " << x << std::endl;
return std::make_pair(x % 2 == 0, x);
}
} only_even;
int main(int argc, char* argv[])
{
auto map = boost::adaptors::transformed;
auto filter = boost::adaptors::filtered;
int v[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto s = v | map(only_even) | filter([](std::pair<bool, int> x)->bool{ return x.first; });
for (auto i : s) {}
return 0;
}
私はこれを実行して、私が取得:
fun: 1
fun: 2
fun: 2
fun: 3
fun: 4
fun: 4
fun: 5
fun: 6
fun: 6
fun: 7
fun: 8
fun: 8
fun: 9
fun: 10
fun: 10
たびにpredicate
がfun
が2回呼び出され、true
です。これは予想される動作ですか?私は何か間違っているか、/これはBoost(私は1.48を使用しています)のバグですか?
編集:私はこれをブーストのトランクバージョンで試してみましたが、それでも起こります。
はい、私はコードを見た後それを考え出しました。 'トランスフォームされた'は意味があり、 'fun'を2回呼びますか?他の言語(Python、Haskellなど)について考えてみると意味がありません。変換が高価な場合はどうなりますか? –
その場合、答えに示されているように「キャッシュされた」アダプターを使用することができます。 –
キャッシュアダプターありがとう!それは問題を解決する:) –