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

0

У меня есть функция f, которая принимает аргумент типа Bar, который имеет 3 параметра шаблона. f не использует ни один из этих трех параметров. Вопрос: компилятор все еще генерирует несколько версий f в зависимости от всех используемых комбинаций A, B и C, или есть лучший способ сделать это?

Пример:

template<typename A, typename B, typename C>
class Bar;

template<typename A, typename B, typename C>
void f(Bar<A,B,C>& bar)
{
  //code that does not use A, B or C, e.g.:
  std::cout << bar.some_getter() << std::endl;
}
Теги:
templates
function
parameters

2 ответа

4
Лучший ответ

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

С другой стороны, если вы возьмете адрес разных экземпляров, у них будет другой адрес, т.е. Даже если компилятор может использовать большую часть идентичного кода, он будет иметь разные адреса, если типы идентичны. Я не уверен, что вы можете сравнивать указатели функций разных типов (наши функции будут иметь другой тип при изменении аргумента Bar<A, B, C>).

Обратите внимание, что даже если f() не может коснуться любого из типов A, B или C, тот факт, что Bar может различаться между экземплярами, может привести к совершенно другому коду, который необходим и, очевидно, сгенерирован.

  • 0
    И, конечно же, тот факт, что вызов &f должен делать то же самое, что и вызов f() напрямую, не означает, что эти функции должны быть одинаковыми. По причинам кэширования компилятор может решить использовать одну версию f в прямых вызовах, но использовать перегрузки, если вы когда-нибудь воспользуетесь &f . Такое предположение непредсказуемо.
2

Компилятор будет генерировать точно количество перегрузок, которые вы в конечном итоге используете, - если ваш код заканчивается вызовом f<A,B,C> для n комбинаций (A,B,C), вы получите n перегрузок. Нет лишнего раздувания. Тем не менее, вывод аргумента шаблона происходит на точных типах. Например, у вас может быть только одна функция

void foo(double x);

И оба эти заявления работают

foo(1);//int implicitly promoted to double
foo(1.0);

Однако, если у вас есть

template <typename T>
foo(T x);

вы в конечном итоге генерируете две перегрузки.

foo(1);//T is deduced to be int, leading to initialization of foo<int>
foo(1.0);//T is deduced to be double, leading to initialization of foo<double>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню