さらに追記
id:ototoiさんに指摘していただいたように
const Item
このやり方だとconst T型、つまり値でもいけるみたいです。
逆にメンバじゃなく演算子関数の引数のほうでは値は使えません。
const Item
さらに、ここでconst TとやってしまうとCRTPを使う意味がなくなりますので最終的にconst Item
メンバをconst Item
#include < typeinfo.h >
template < typename T >
struct Item
{
const T& Self() const
{
return static_cast< const T& >(*this);
}
};template < typename T,typename U >
struct Plus:public Item< Plus >
{
Plus(const Item< T >& t,const Item< U >& u)
:ft(t.Self()),fu(u.Self())
{
}
int operator[](std::size_t i)const
{
return ft[i]+fu[i];
}
const T ft;
const U fu;
};template< typename T,typename U >
inline Plus< T,U > operator+(const Item< T >& t, const Item< U >& u)
{
return Plus< T,U >(t,u);
}template < typename T,typename U >
struct Multiple:public Item< Multiple >
{
Multiple(const Item< T >& t,const Item< U >& u)
:ft(t.Self()),fu(u.Self())
{
}
int operator[](std::size_t i)const
{
return ft[i]*fu[i];
}
const T ft;
const U fu;
};template< typename T,typename U >
inline Multiple< T,U > operator*(const Item< T >& t, const Item< U >& u)
{
return Multiple< T,U >(t,u);
}struct Vec:public Item< Vec >
{
int f[3];Vec(int a,int b,int c)
{
f[0]=a;
f[1]=b;
f[2]=c;
}template < typename T >
Vec& operator=(const Item< T >& t)
{
for(int i=0;i< 3;++i)f[i]=t.Self()[i];
return *this;
}int operator[](std::size_t i)const
{
return f[i];
}
};int _tmain(int argc, _TCHAR* argv[])
{
Vec a(1,2,3);
Vec b(4,5,6);
Vec c(7,8,9);using namespace std;
//42
cout << (a+b*c)[1] << endl;
//struct Plus< struct Vec,struct Multiple< struct Vec,struct Vec > >
cout << typeid(a+b*c).name() << endl;return 0;
}