2015-02-04 5 views
8

В чем разница между следующими 2 частями коды:аргументов шаблона против аргументов функции

1:

template<size_t min, size_t max> 
bool byLength(const std::string& v) 
{ 
    return v.length() >= min && v.length() <= max; 
} 

2:

bool byLength(const std::string& v, size_t min, size_t max) 
{ 
    return v.length() >= min && v.length() <= max; 
} 

Главная Прецедент использовать аргументы шаблона вместо аргументов функции? Почему бы просто не использовать второй пример?

+7

Шаблоны разрешены * время компиляции *, аргументы оцениваются в * время выполнения *. Это означает, что аргументы шаблона должны быть постоянными, чтобы быть разрешенными компилятором, в то время как аргументы функции могут быть такими, как использование-ввод, которые невозможно оценить во время компиляции. –

+0

Хорошо, похоже, я понимаю глупость вопроса. Могу ли я удалить его? –

+1

Вы называете их по-разному: 'byLength (строка)' vs 'byLength (строка, min, max)'. Если это имеет значение для ваших глаз. – rubikonx9

ответ

9

в чем разница между следующими 2 частями коды?

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

Для иллюстрации с шаблоном:

byLength<5,10>(v);  // OK 

size_t min,max; 
std::cin >> min >> max; 
byLength<min,max>(v); // ERROR: must be constants 

в то время как аргументы функции:

byLength(v, 5, 10);  // OK 

size_t min,max; 
std::cin >> min >> max; 
byLength(v, min, max); // OK 

Главная Прецедент использовать аргументы шаблона вместо аргументов функции?

Будучи константами, они могут дать лучшую оптимизацию и могут использоваться в ситуациях (таких как размер массива), где допускаются только константы.

Почему бы просто не использовать второй пример?

В этом случае, почему бы и нет? Это было бы более гибким, поскольку вы могли бы рассчитать аргументы во время выполнения или получить их из ввода программы. Если он встроен, тогда он должен быть таким же эффективным, как и шаблон при вызове с постоянными значениями.

2

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

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

По существу, вторая функция позволяет сделать это

int a, b; 
cout << "Please enter two limits: "; 
cin >> a >> b; 
string s("quick brown fox"); 
bool res = byLength(s, a, b); 

Это не возможно с помощью функции шаблона:

int a, b; 
cout << "Please enter two limits: "; 
cin >> a >> b; 
string s("quick brown fox"); 
bool res = byLength<a,b>(s); // <<== DOES NOT COMPILE. 

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

Почему бы просто не использовать второй пример?

Бывают ситуации, когда в вашей функции требуется постоянная времени компиляции. Например, если вы хотите объявить std::array<len> на основе одного из параметров, он должен быть передан в качестве параметра шаблона, а не в качестве обычного параметра:

template<size_t sz> 
void demo() { 
    std::array<sz> data; 
    ... 
} 

То же не будет работать с регулярными параметрами функции:

void demo(size_t sz) { 
    std::array<sz> data; // <<== DOES NOT COMPILE. 
    ... 
} 
1

Вы не можете вызвать шаблон со значениями, которые не являются consexpr.

Простейшим примером может быть что-то вроде этого:

1 Может быть вызвана с этим кодом:

const auto Min = numeric_limits<int>::min(); 
const auto Max = numeric_limits<int>::max(); 

byLength<Min, Max>(string()); 

Вы должны использовать 2 для значений, известных только во время выполнения:

cin >> Min >> Max; 

// Cannot call by byLength<Min, Max>(string()); because the values are not constexpr 
byLength(string(), Min, Max); 
Смежные вопросы