2013-07-21 4 views
-2

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

#include <iostream> 
#include <cstdint> 
#include <vector> 

template <uint8_t VAL> 
void foo() 
{ 
    std::cout << "__" << std::endl; 
}; 

template <> 
void foo<3>() 
{ 
    std::cout << "OK" << std::endl; 
}; 

int main() 
{ 
    std::vector<uint8_t> v = { 2, 4, 5, 2, 3, 55 }; 
    for (auto &k : v) { 
     foo<k>(); 
    } 
    return (0); 
} 

компилятор в основном жалуется на k, не будучи a constant expression, проблема в том, что я понятия не имею, как это изменить, чтобы сделать эту работу, мне нужна некоторая структура данных для повторения, поэтому мне нужно сохранить вектор, мне нужно шаблон, чтобы упростить мою жизнь, поэтому чем больше я вижу это, тем больше чувствую себя в ловушке бесконечного цикла.

+2

Нет, это не прецедент для шаблона. Это вариант использования if if (i == 3) cout << "OK"; '. –

+0

@ H2CO3 что вы имеете в виду? Вы можете скопировать числовое значение, это точно, что перегрузка с '<3>' есть только, чтобы проверить что-то на вызове шаблона. Мне нужно создать числовое значение. – user2485710

+0

@userXXX Я знаю, что вы можете использовать ** целое число ** (не любое число) в качестве аргумента шаблона. Однако не переменная, а только константа времени компиляции. Я говорю, что я не вижу необходимости в шаблоне. Это может быть проблемой XY. –

ответ

3

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

#include <iostream> 

void print(int t) { 
    static char const *s [] = { "__", "OK" }; 
    std::cout << s[t == 3]; 
} 

void print() {} 

template<typename... Args> 
void print(int n, Args ... args) { 
    print(n); 
    print(args...); 
} 

int main() { 
    print(2, 4, 5, 2, 3, 55); 
} 

Результат:

________OK__ 

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

0

У компилятора нет возможности вывести возможные значения для k во время компиляции, поэтому я не вижу, как это может работать?

+0

вот что мне нужно исправить, я обычно не задаю вопросы о вещах, которые уже работают: D – user2485710

0

Нет, это не сработает для непостоянных выражений. Просто сделайте простую старую функцию:

#include <iostream> 
#include <cstdint> 
#include <vector> 

void foo(uint8_t VAL) 
{ 
    if(VAL == 3) 
     std::cout << "OK" << std::endl; 
    else 
     std::cout << "__" << std::endl; 
}; 

int main() 
{ 
    std::vector<uint8_t> v = { 2, 4, 5, 2, 3, 55 }; 
    for (auto &k : v) { 
     foo(k); 
    } 
return (0); 
} 
1

Вы не должны использовать шаблон, если все, что нужно идти <here> не может быть выведено на время компиляции тривиальным. В этом случае k не является постоянным выражением, поэтому вы не можете использовать его в качестве аргумента шаблона.

Шаблоны не волшебный молот. У них много прецедентов, но вы не можете использовать их абсолютно для всех.

В этом конкретном фрагменте кода foo должно быть определено как void foo(uint8_t).


да, Infact моя проблема в том, как превратить этот вектор в постоянной во время компиляции набора значений, реальная проблема это на самом деле не о шаблонах.

Возможно, вы сможете осуществить это с использованием вариативных шаблонов. Вместо использования вектора вы должны использовать интегральные константы непосредственно в вариационном шаблоне (foo<2, 4, 5, 2, 3, 55>).

Я не очень увлечен ими, поэтому это займет некоторое время.

Редактировать: Джерри избил меня.

+0

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

+0

В качестве параметров шаблона просто невозможно использовать значения времени выполнения. Шаблоны - это функции времени компиляции. Отсюда необходимость в постоянных выражениях. – iolo

1

Если вы действительно хотите способ перебрать время компиляции постоянного список целочисленных значений:

#include <iostream> 
#include <cstdint> 

template <uint8_t VAL> 
inline void foo() 
{ 
    std::cout << "__" << std::endl; 
} 

template <> 
void foo<3>() 
{ 
    std::cout << "OK" << std::endl; 
} 

template <uint8_t... Values> 
struct FooHelper { 
    static void foo_all() { 
    } 
}; 

template <uint8_t First, uint8_t... Rest> 
struct FooHelper<First, Rest...> { 
    static void foo_all() { 
    foo<First>(); 
    FooHelper<Rest...>::foo_all(); 
    } 
}; 

template <uint8_t... Values> 
void foo_all() 
{ 
    FooHelper<Values...>::foo_all(); 
} 

int main() 
{ 
    foo_all<2, 4, 5, 2, 3, 55>(); 
} 

Хотя я честно не вижу случай использования для него.

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