0

Я пытаюсь добавить еще один аргумент шаблона к факториальному примеру метапрограммирования. Но следующее не работает. Каков правильный путь?шаблон с одним явным аргументом

Код:

#include <iostream> 

template <typename T, int Depth> 
inline void loop(T i){ 
    std::cout << i; 
    loop<T, Depth-1>(i - 1); 
} 
template <typename T, int Depth> 
inline void loop<T, 0>(T i){ 
    std::cout << i << std::endl; 
} 

int main(void){ 
    int i = 10; 
    loop<int, 3>(i); 
} 

Ошибка:

test4.cpp(9): error: an explicit template argument list is not allowed on this declaration 
    inline void loop<T, 0>(T i){ 

ответ

6

Вы не можете частично специализировать шаблоны функций. Полная остановка.

В C++ 17, вы сможете написать:

template <typename T, int Depth> 
inline void loop(T i){ 
    std::cout << i; 
    if constexpr (Depth > 0) { 
     loop<T, Depth-1>(i - 1); 
    } 
} 

до тех пор, я не хотел бы предложить только с глубины в качестве integral_constant аргумента:

template <typename T> 
inline void loop(T i, std::integral_constant<int, 0>) { 
    std::cout << i << std::endl; 
} 

template <typename T, int Depth> 
inline void loop(T i, std::integral_constant<int, Depth>){ 
    std::cout << i; 
    loop(i - 1, std::integral_constant<int, Depth-1>{}); 
} 
+0

как назвать этот цикл? Я имею в виду, как должна выглядеть основная функция? –

+0

Я получаю сообщение об ошибке, если я использую 'int main (void) { int i = 10; loop (i, std :: integ_constant {}); } 'и скомпилировать с помощью g ++ -std = C++ 14. Ошибка - глубина создания шаблона превышает 900. –

+0

@rxu теперь код должен работать как ожидалось –

4

Вы можете использовать вспомогательный класс и его специализация для выполнения реальной работы.

template <typename T, int Depth> struct LoopHelper 
{ 
    static void doit(T i) 
    { 
     std::cout << i; 
     LoopHelper<T, Depth-1>::doit(i); 
    } 
}; 

template <typename T> struct LoopHelper<T,0> 
{ 
    static void doit(T i) 
    { 
     std::cout << i; 
    } 
}; 


template <typename T, int Depth> 
inline void loop(T i){ 
    LoopHelper<T, Depth>::doit(i); 
} 

Дополнительное уточнение

Я бы рекомендовал изменения loop разрешить вычет T.

template <int Depth, typename T> 
inline void loop(T i){ 
    LoopHelper<T, Depth>::doit(i); 
} 

Затем, вы можете использовать:

int i = 10; 
loop<3>(i); 

и пусть T выводится в int.

+0

'loop (i);' работает. –

+0

@ rxu, Да, это так. Я протестировал его, прежде чем отправил ответ. –

Смежные вопросы