boost::make_adaptable

make_adaptable undocumented(#4532)


「Boost.Bindにあるmake_adaptableがdetail名前空間じゃないのにドキュメンテーションされてないぞ」というチケットがあったので、解説など。


std::not1やstd::not2など、旧世代の悪しき標準関数アダプタは、関数オブジェクトにresult_typeや
argument_type、first_argument_type、second_argument_typeといったnested typeを直接要求するため、boost::bindした関数オブジェクトを標準関数アダプタに適用することができません。

#include <functional>
#include <boost/bind.hpp>
#include <boost/assert.hpp>

bool is_less(int a, int b) { return a < b; }

int main()
{
    const bool result = std::not1(boost::bind(is_less, 1, _1))(2); // エラー!argument_typeを持っていない
    BOOST_ASSERT(!result);
}

そんな標準関数アダプタのために用意されているのがboost::make_adaptableです。
関数オブジェクトをmake_adaptableでラップすることによって標準関数アダプタが要求するnested typeを後付けすることができます。

#include <functional>
#include <boost/bind.hpp>
#include <boost/bind/make_adaptable.hpp>
#include <boost/assert.hpp>

bool is_less(int a, int b) { return a < b; }

int main()
{
    const bool result =
        std::not1(boost::make_adaptable<bool, int>(boost::bind(is_less, 1, _1)))(2); // OK
    BOOST_ASSERT(!result);
}

今までこういったケースでは自前のnot1を書いていたので、やっとまともに使えるようになりました。