Специализация шаблона и оптимизация компилятора - PullRequest
0 голосов
/ 21 мая 2018

У меня есть класс с логическим аргументом шаблона.

template<bool b>
class Foo {
  void doFoo();
};

Я хочу, чтобы doFoo делал разные вещи, основываясь на значении b.

Наивно я мог бы написать

Вариант 1

template<bool b> void Foo<b>::doFoo() {
  if (b) cout << "hello";
  else cout << "goodbye";
}

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

Вариант 2

template<> void Foo<true>::doFoo() { cout << "hello"; }
template<> void Foo<false>::doFoo() { cout << "goodbye"; }

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

Мой вопрос, достаточно ли умен компилятор, чтобы знать, что не следует выполнять условие в варианте 1, поскольку он всегда выполняется одинаково или мне нужно написать специализации?Если компилятор достаточно умен, я был бы рад узнать, зависит ли это от компилятора или от языковой функции, на которую я могу положиться?

Ответы [ 2 ]

0 голосов
/ 21 мая 2018

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

Компилятор , вероятно, оптимизирует это, но это не так.гарантируется стандартом.Чтобы быть уверенным, вы должны взглянуть на вывод нужного вам компилятора (с опциями компиляции, которые вы планируете использовать): например.У clang нет ветки в связанном примере (в неоптимизированной версии много шаблонов вызовов функций, но нет ветки).

В C ++ 17 вы можете использовать if constexpr, а ветвь, которая не занята, будет отброшена во время компиляции.

0 голосов
/ 21 мая 2018

Компилятор, вероятно, оптимизирует ветку, поскольку во время компиляции известно, что такое b.Это не гарантируется, и единственный способ узнать наверняка - проверить сборку.

Если вы можете использовать C ++ 17, вы можете использовать if constexpr, и это гарантирует, что будет существовать только одна ветвь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...