boost::call_traitsを使った最適化
boost::call_traits
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度も記述しなければならないあたりが。
何か良い方法はないだろうか?