Как написать функции шаблона CPP, которые рекурсивны по длине массива аргументов

Скажем, я хочу написать функцию arrfill<N>который заполняет массив длины. Ниже представлена ​​реализация шаблона, который я пробовал.

      template<typename T>
bool arrfill(T arr[0], T v){;}

template<size_t N, typename T>
void arrfill(T arr[N], T v){
    arr[0] = v;
    arrfill<N-1>(arr+1, v);
}

int main(int argc, char const *argv[])
{
    bool barr[4];
    arrfill<4>(barr, true);
}

Однако это не будет компилироваться, поскольку создание экземпляра шаблона не завершится в том случае, если N является 0 и превысит его максимальную глубину.

Похоже, что компиляторы не примут размер массива в подписи в качестве типа аргумента. Интересно, как правильно это указать?

2 ответа

Вы постепенно приходите в упадок.

      template<typename T>
bool arrfill(T (&arr)[1], T v){arr[0]=v;}

template<size_t N, typename T>
void arrfill(T (&arr)[N], T v){
  arr[0] = v;
  arrfill(*reinterpret_cast<T(*)[N-1]>(arr+1), v);
}

который является UB, который работает во всех компиляторах.

Действительно, используйте пачки и складные.

      template<size_t N, typename T,std::size_t...Is>
void arrfill(T (&arr)[N], T v,std::index_sequence<Is...>){
  ((void)(arr[Is]=v),...);
}
template<size_t N, typename T>
void arrfill(T (&arr)[N], T v){
  arrfill(arr, v, std::make_index_sequence<N>{});
}

или просто используйте std fill_n

Я пришел с решением, определив новый класс, кодирующий информацию о длине. Но мне интересно, самый ли это изящный способ.

      template<size_t N>
struct intClass{};

template<typename T>
bool arrfill(T arr[0], T v, intClass<0>){;}

template<size_t N, typename T>
void arrfill(T arr[N], T v, intClass<N>){
    arr[0] = v;
    arrfill(arr+1, v, intClass<N-1>());
}

template<size_t N, typename T>
void arrfill(T arr[N], T v){
    arrfill(arr,v, intClass<N>());
}
Другие вопросы по тегам