読者です 読者をやめる 読者になる 読者になる

ボレロ村上 - ENiyGmaA Code

中3女子です。

boost::call_traitsを使った最適化


boost::call_traits::param_typeは、Tが(constな)引数にとられるとき
const参照渡しにすべきか、値渡しにすべきか決定してくれます。


以下のように使う。

#include <boost/call_traits.hpp>

template<typename T>
class foo {
public:
    typedef typename boost::call_traits<T>::param_type param_t;
    static void do_something(param_t v) { /* ... */ }
};

struct heavy_t { int i[100]; };


foo<int>::do_something(0);                // param_t == int const
foo<heavy_t>::do_something(heavy_t());    // param_t == heavy_t const&


どうせなら、こうして使ってみたくなるのが人情。

#include <boost/call_traits.hpp>

template<typename T>
void do_something(typename boost::call_traits<T>::param_type v) { /* ... */ }

do_something(0);    // NG! パラメータTを推論できない


こういう場合自分は、たいがい以下のように書いている。

#include <boost/call_traits.hpp>
#include <boost/utility/enable_if.hpp>
#include <sprig/type_traits/is_call_reference_param.hpp>

template<typename T>
typename boost::enable_if<
    sprig::is_call_reference_param<T>
    // == boost::is_reference<typename boost::call_traits<T>::param_type>
>::type do_something(T const& v) { /* ... */ }

template<typename T>
typename boost::disable_if<
    sprig::is_call_reference_param<T>
    // == boost::is_reference<typename boost::call_traits<T>::param_type>
>::type do_something(T const v) { /* ... */ }

いかんせん汚い。とくに、本質的に同じコードを
2度も記述しなければならないあたりが。


何か良い方法はないだろうか?