Если у меня есть функция
int calcStuff_dynamic(const int a, const int b)
и некоторый шаблон мета-кода
template<int a, int b>
struct calcStuff_static {
static const int value = //some more code
};
Есть ли способ написать обертку
int calcStuff(const int a, const int b) {
IF_THESE_ARE_KNOWN_CONSTANTS_AT_COMPILE_TIME(a, b)
return calcStuff_static<a, b>::value;
ELSE_TEMPLATE_WOULD_FAIL
return calcStuff_dynamic(a, b);
}
Вы не можете сделать это, но это будут делать умные компиляторы.
Может быть, первое решение, которое приходит на ум, это использовать SFINAE в сочетании constexpr ценности. В этом случае нам нужно что-то обнаружить constexpr ценности.
Но нет is_constexpr
или что-то подобное, чтобы обнаружить значения, которые известны во время компиляции. С другой стороны, функция is_const
не полезно, потому что constexpr
не является частью типа. Таким образом, вы не можете сделать это (или, по крайней мере, я не знаю прямого решения).
Однако вы будете рады, если знаете, что существует оптимизация многих компиляторов, которая вычисляет окончательное значение функции для известных значений во время компиляции. Например, в GCC есть «Замена окончательной стоимости SCEV».
Поэтому вы должны просто использовать эту динамическую функцию, когда параметры неизвестны, и компилятор сделает это по вашему желанию (если это возможно).
GCC, Clang и компилятор Intel все поддерживают __builtin_constant_p проверить, является ли значение постоянной времени компиляции и предоставить оптимизированное выражение в этом случае.
Для всех других компиляторов вы можете использовать динамическое вычисление как запасной вариант. (Я не знаю, что есть аналог для Visual Studio.)