きっかけはSFINAE
スカラーまたは範囲に対して、同様の操作をそれぞれ定義したいと思った。 もちろんオーバーロードによって同様の関数名として定義したい。 範囲に対する操作を定義するときは、C++標準に倣うとIteratorを使うことが多いので、次のようなコードだ。
template<typename Tin, typename Tio>
void add(Tin first, Tin last, Tio io)
{
if(first != last)
{
*io += *first;
while(++first != last)
*++io += *first;
}
}
template<typename Tio, typename T>
void add(Tio first, Tio last, T v) // error: redefine
{
if(first != last)
{
do
{
*first += v;
}
while(++first != last);
}
}
関数のシグネチャが同一なので再定義になっておりコンパイルできぬ。 では3つめの引数の型で呼出を切り替えるようなSFINAEにしてみよう。 これが、思ったよりは簡単でなかったという話。