1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

boost::fusion::make_fused_procedureが何者か調べるだけの記事

Posted at

boostのリファレンスより

https://www.boost.org/doc/libs/1_81_0/libs/fusion/doc/html/fusion/functional/adapters/fused_procedure.html

An unary Polymorphic Function Object adapter template for Callable Object target functions. It takes a Forward Sequence that contains the arguments for the target function.

The result is discarded and the adapter's return type is void.

The type of the target function is allowed to be const qualified or a reference. Const qualification is preserved and propagated appropriately (in other words, only const versions of operator() can be used for a target function object that is const or, if the target function object is held by value, the adapter is const - these semantics have nothing to do with the const qualification of a member function, which is referring to the type of object pointed to by this which is specified with the first element in the sequence passed to the adapter).

If the target function is a pointer to a members function, the corresponding object can be specified as a reference, pointer, or smart pointer. In case of the latter, a freestanding get_pointer function must be defined (Boost provides this function for std::auto_ptr and boost::shared_ptr).

The target function must not be a pointer to a member object (dereferencing such a pointer without returning anything does not make sense, so this case is not implemented).

全然頭に入ってこない。

実験

こんなコードを書いてみる

#include <iostream>
#include <boost/range/algorithm/for_each.hpp>
#include <boost/range/combine.hpp>
#include <boost/bind/bind.hpp> 
#include <boost/fusion/adapted/boost_tuple.hpp>
#include <boost/fusion/functional/generation/make_fused_procedure.hpp>

void f(int n, bool b)
{
    std::cout << n << ',' << b << std::endl;
}
int main()
{
    using namespace boost::placeholders;
    std::vector<int> v = { 2, 4, 7 };
    std::vector<bool> state = { true, true, false };
    boost::for_each(boost::combine(v, state), boost::fusion::make_fused_procedure(boost::bind(f, _1, _2)));
}

実行結果

2,1
4,1
7,0

boost::combineの結果、for_eachから得られる要素型は概ねboost::tuple<int, bool>のようになっているはずです。

これに対して関数fの引数は(int, bool)です。

つまりboost::fusion::make_fused_procedureでラップすることでいい感じにtupleをsequenceとしてあつかい、展開して渡してくれるということなのでしょう。

C++17において

もっとも今となっては構造化束縛を用いて明示的にこんなふうに書いたほうがわかりやすい気がします。

boost::for_each(boost::combine(v, state), [](auto&& t) {
    auto&& [n, b] = t;
    return f(n, b);
});

あるいはもっと汎用的に書くならstd::applyでもいい気がします。

boost::for_each(boost::combine(v, state), [](auto&& t) {
    return std::apply(f, t);
});

・・・と思ったんですけど、これは書きにくいという昔の記事を見かけたのでなるほど・・・?という気持ちです。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?