Специализация шаблона или условные выражения?

69
6

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


Вопрос: каковы преимущества специализации?


Это:


template <int i> class A {};
template <> class A <1> { void foo() {/* something */} };
template <> class A <2> { void foo() {/* something else*/} };
template <> class A <3> { void foo() {/* even different*/} };

Лучше (более быстрое выполнение), чем


template <int i> class A { 
void foo() {
if (i==1) {/* something */}
else if (i==2) {/* something else*/}
else if (i==3) {/* even different*/}
}
};

?


Edit:


Код является частью библиотеки, которая будет использоваться другими.
Я использую gcc 4.6.3, но в конце код будет использоваться с разными компиляторами.


Edit:


Эти две части кода приводят к идентичным двоичным файлам, использующим gcc 4.6.3. Я не могу проверить полный случай, так как мой фактический код далеко не годный для использования. Это, по-видимому, принципиально, versatiliy, повторное использование, maintanability и т.д.

спросил(а) 2012-07-01T22:35:00+04:00 7 лет, 7 месяцев назад
1
Решение
90

Скорость не является основной проблемой здесь, но расширяемость.


Специализация имеет то преимущество, что вы упрощаете клиентам вашего кода добавлять новые перегрузки foo(). Предположим, что позже вы решили добавить новое поведение для i=4: в первом подходе вы просто добавляете новую специализацию; во второй версии вам необходимо изменить функцию foo(). Если вы выпустили свою библиотеку в двоичной форме, клиенты не будут счастливы.

Предпочтение специализации подход ко второй является проявлением Открытый/Закрытый Принцип: код должен быть открыт для расширения, закрыт для модификации.

ответил(а) 2012-07-01T23:00:00+04:00 7 лет, 7 месяцев назад
60

Иногда невозможно написать код как одну функцию, потому что код, действительный для i=1, может быть недопустим для i=2, и даже если он никогда не выполняется, компилятор задыхается!


Например:

template <int i> class A { 
void foo() {
if (i==1)
{
cout << "Easy";
}
else if (i==2)
{
int stuff[100 * i - 110] = {42}; // error: negative array size for i=1
cout << stuff[0];
}
else if (i==3)
{
/* even different*/
}
}
};

ответил(а) 2012-07-01T23:51:00+04:00 7 лет, 7 месяцев назад
61

Вы спрашиваете: "Почему шаблонная специализация лучше", но позвольте мне сказать, почему это хуже. Я предполагаю, что по крайней мере некоторые из кода для i=1, i=2 и i=3 являются общими (в противном случае, почему это одно и то же имя?). Если это так, вам придется дублировать код, когда вы идете на специализацию, и это затрудняет работу с кодом.


Кодирование кода лучше оставить компилятору, что довольно хорошо с этими конструкциями if-elseif-else. У вас может даже быть if (i<3), что было бы очень неудобно реализовать со специализацией.


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

ответил(а) 2012-07-01T23:11:00+04:00 7 лет, 7 месяцев назад
60

Это зависит от используемого компилятора. Я сам пишу код, и мой компилятор делает для меня все правильно. Однако, поскольку ничто в стандарте С++ не требует, чтобы компиляторы были умны в этом отношении, вы также можете столкнуться с проблемой. Поэтому убедитесь, что ваш компилятор поступает правильно. Как правило, не полагайтесь на эту функцию, если вы пишете библиотеку многократного использования, предназначенную для использования кем-то другим, если вы планируете переносить этот код на разные компиляторы и/или на экзотические среды и т.д.

ответил(а) 2012-07-01T22:43:00+04:00 7 лет, 7 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема