サンプルの動作確認バージョン [GCC4.4/1.41.0] [VC9/1.41.0]
#include <iostream>
#include <cstring>
#include <boost/type_traits.hpp>
#include <boost/utility/enable_if.hpp>
using namespace std;
using namespace boost;
template<typename T>
void copy_n( const T* from, int n, T* to,
typename enable_if< is_pod<T> >::type* =0 )
{
cout << "memcpy ver" << endl;
memcpy( to, from, sizeof(T)*n );
}
template<typename T>
void copy_n( const T* from, int n, T* to,
typename disable_if< is_pod<T> >::type* =0 )
{
cout << "forloop ver" << endl;
for(int i=0; i!=n; ++i)
*to++ = *from++;
}
struct NonPod
{
NonPod(){}
~NonPod(){}
void operator=(const NonPod&){}
};
int main()
{
char x[10];
NonPod y[10];
copy_n( x, 10, x ); // memcpy版が呼ばれる
copy_n( y, 10, y ); // forループ版が呼ばれる
return 0;
}
memcpy ver forloop ver
テンプレート引数がポインタの場合とそうでない場合、のような場合分けは、 テンプレートの部分特殊化によって記述することができました。 enable_ifは、MPLやtype_traitsを使った複雑な条件式に基づいて テンプレートの有効/無効を切り替えるのに使います。
上のサンプルでは、TがPOD型の時にはmemcpy版が有効になり、 逆にPOD型でないときはforループ版が有効になっています。