以下のように再帰させようとすると、失敗する。
関数テンプレートでは、テンプレート引数による再帰はできない模様。
template<int N,class T,typename std::enable_if<(N==0)>::type* = nullptr>
auto add_pointers(T) -> T*;
template<int N,class T,typename std::enable_if<(N > 0)>::type* = nullptr>
auto add_pointers(T) -> decltype(add_pointers<N-1>(std::declval<T*>()));
int main()
{
decltype(add_pointers<0>(std::declval<int>())) val1;
std::cout<<typeid(val1).name()<<std::endl;
decltype(add_pointers<1>(std::declval<int>())) val2;
std::cout<<typeid(val2).name()<<std::endl;
//以下をコメントアウトすると、コンパイルが通る
decltype(add_pointers<2>(std::declval<int>())) val3;
std::cout<<typeid(val3).name()<<std::endl;
}
以下のように、関数の引数の型を変えれば、再帰させることが可能。
template<int N>
struct int_{};
template<int N,class T,typename std::enable_if<(N > 0)>::type* = nullptr>
auto add_pointers(T,int_<N>) -> decltype(add_pointers(std::declval<T*>(),int_<N-1>()));
template<int N,class T,typename std::enable_if<(N==0)>::type* = nullptr>
auto add_pointers(T,int_<N>) ->T;
int main()
{
decltype(add_pointers(std::declval<int>(),int_<3>())) a;
std::cout<<typeid(a).name()<<std::endl;
}