2015-12-19 3 views
0

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

template<typename T, typename = std::enable_if_t<std::is_integral<T>::value>> 
void fun(const T& val) 
{ 
    std::cout << "val >= 0"; 
} 

int main() 
{ 
    fun(34); 
} 

Представьте, что есть и другие перегруженные функции. Как я могу получить вышеперечисленную функцию перегрузки только для компиляции, когда значение val больше, чем 0?

На http://en.cppreference.com/w/cpp/types/is_integral я вижу, что operator() перегружен для std::is_integral и возвращает value поэтому я попытался это:

template<typename T, typename = std::enable_if_t<std::is_integral<T>::value() > 0>> 

Конечно, это выглядит не так, и это не так, как компилятор милостиво позволяет мне знать.

Как проверить значение переменной во время компиляции?

+4

Переменная не имеет значения во время компиляции, только во время выполнения. –

+0

@AlanStokes Только опция должна иметь значение как параметр шаблона? template DeiDei

+1

Или вы можете посмотреть на функцию 'constexpr'. –

ответ

3

Короткий ответ: вы не можете.

Значение входных параметров функции определяется во время выполнения. Таким образом, SFINAE не поможет в этом, и никто не будет компилировать тайм-аут.

Что вы можете сделать, это атаковать проблему во время выполнения и определить две независимые функции, которые собираются быть вызваны соответственно:

template<typename T, typename = std::enable_if_t<std::is_integral<T>::value>> 
void fun(const T& val) 
{ 
    (val < 0)? lower_than_zero(val) : greater_equal_than_zero(val); 
} 

Но, вероятно, вы знали, что уже. Если вы все еще хотите оценить время компиляции, и вы уверены, что ваша переменная является компилятором времени. Тогда вы могли бы передать его в качестве шаблона, не аргумент типа:

template<int N> 
std::enable_if_t<N >= 0> fun() { 
    std::cout << "N >= 0" << std::endl; 
} 

template<int N> 
std::enable_if_t<N < 0> fun() { 
    std::cout << "N < 0" << std::endl; 
} 

int main() { 
    fun<42>(); 
    fun<-42>(); 
} 
+0

, но предположим, что значение «val» доступно во время компиляции, например, используя параметр шаблона не типа (сделайте какое-либо необходимое предположение, пожалуйста), то это могло бы быть сделано с помощью оператора 'if'? Спасибо –

+0

@AngelusMortis, что вы описываете, является статическим, если. К сожалению, у C++ нет статического if. По крайней мере, пока. – 101010

+0

Значит, 'if' всегда оценивает его выражение во время выполнения и ветвей соответственно? Благодарю . –

0

Как @ 101010 ответил нет никакого способа сделать это в общем виде. Но если вам нужно проверить только одно условие >= 0, то вы можете сделать это:

void ff(unsigned int val) { 
    val = 42; 
} 

int main() 
{ 
    ff(34); 
    ff(-34); 
} 

и компилировать как это:

g++ 1.cpp -Werror -Wsign-conversion 

Но это просто хак для одного частного случая.

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