2015-03-18 3 views
4

Я пытался использовать переменные шаблоны так же, как я использую некоторые другие шаблоны, например: мы уже знаем, как вычислить Fibonacci number или power of a number, используя метапрограммирование с помощью template objects wrapping a static value or a enum value.Рекурсивные шаблоны переменных

Итак, первое, что я сделал, пытаясь специализироваться переменным шаблон, и он работает, как ожидалось:

template <std::size_t VALUE> std::size_t value  = VALUE; 
template <>     std::size_t value<666u> = 1u; 

std::cout << value<0u> << '\n'; // "0" as expected 
std::cout << value<1u> << '\n'; // "1" as expected 
std::cout << value<2u> << '\n'; // "2" as expected 
std::cout << value<666u> << '\n'; // "1" as expected!! 

Зная, что переменная шаблона специализация возможно я пытался сделать переменный шаблон числа Фибоначчи :

template <std::size_t ITERATION> 
std::size_t fibonacci = fibonacci<ITERATION - 1u> + fibonacci<ITERATION - 2u>; 
template <> std::size_t fibonacci<1u> = 1u; 
template <> std::size_t fibonacci<0u> = 0u; 

int main() 
{ 
    std::cout << fibonacci<5> << '\n'; // "8" expected; 
    return 0; 
} 

ошибка я получаю от Wandbox является следующее:

error: expected primary-expression before ';' token 
template <std::size_t ITERATION> std::size_t fibonacci = fibonacci<ITERATION - 1u> + fibonacci<ITERATION - 2u>; 
                              ^

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

Подсказка?

Большое спасибо.

ответ

2

Мое предположение заключается в том, что компиляторы еще не внедряют шаблоны переменных правильно. Например, clang 3.7.0 компилирует ваш код, но (с небольшим исправлением ошибки: fibonacci<0u> = 1u) выходы 0 вместо 8 для fibonacci<5>.

Однако, если мы делаем

std::cout << fibonacci<0> << '\n'; // "1" expected; 
std::cout << fibonacci<1> << '\n'; // "1" expected; 
std::cout << fibonacci<2> << '\n'; // "2" expected; 
std::cout << fibonacci<3> << '\n'; // "3" expected; 
std::cout << fibonacci<4> << '\n'; // "5" expected; 
std::cout << fibonacci<5> << '\n'; // "8" expected; 

тогда мы получим ожидаемые результаты. Weird!

Update Поскольку шаблоны функций являются более зрелыми, чем переменные шаблоны, следующий обходной путь:

template <std::size_t ITERATION> 
constexpr std::size_t get_fibonacci() 
{ 
    return get_fibonacci<ITERATION - 1u>() + get_fibonacci<ITERATION - 2u>(); 
} 

template <> 
constexpr std::size_t get_fibonacci<0u>() { 
    return 1u; 
} 

template <> 
constexpr std::size_t get_fibonacci<1u>() { 
    return 1u; 
} 

template <std::size_t ITERATION> 
std::size_t fibonacci = get_fibonacci<ITERATION>(); 
+0

Ну, ожидаемые результаты могут быть достигнуты только с правильным кодом; если у меня была ошибка или опечатка, нет способа получить «8» для 5-го номера Фибоначчи;) в любом случае кажется, что моя проблема выпущена для того, как компилятор реализует VT, так что это облегчает работу кода , Большое спасибо! –

+0

Я бы обвинил стандарт, а не сами поставщики компилятора –

+1

@PiotrS. Оказывается, большинство поставщиков компиляторов являются членами комитета Standard. Я хочу сказать, что, вероятно, это всего лишь вопрос времени, пока реализация не станет понятной. –

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