在 constexpr 评估上分支/在 constexpr 上重载

Branching on constexpr evaluation / overloading on constexpr

设置:

我有一个使用 SIMD 内在函数的函数,想在一些 constexpr 函数中使用它。

为此,我需要将其设为 constexpr。但是,SIMD 内在函数没有标记为 constexpr,编译器的常量求值器无法处理它们。

我尝试用执行相同操作的 C++ constexpr 实现替换 SIMD 内在函数。该函数在 运行 时变慢了 3.5 倍,但我能够在编译时使用它(是吗?)。

问题

如何在常量表达式中使用这个函数,而不会在 运行 时减慢我的程序?

一些想法:

更务实的解决方案是:

无论如何,我愿意接受任何能解决我的问题的建议。

提示:

尝试失败:

我会这样做

constexpr int doit(int input, bool inconst = false) {
   return inconst ? doitconsty(input) : doitfast(input);
}

如果对 doit 的调用在 constexpr 函数内部,可以在运行时或编译时调用它来执行某些操作,只需转发标志

constexpr int f(int n, bool inconst = false) {
   /* ... */
   int importantInt = doit(n / 42, inconst);
   /* ... */
   return magicResult;
}

任何 constexpr 评估都有它开始的地方,如果我没记错的话。将 inconst 传递到那里

enum foo { bar = f(256, true) }

如果您在运行时世界中,只需调用 f 就像调用其他任何东西一样

int main() { std::cout << "test-case: " << f(256); }

需要注意的是,这对运算符不起作用,因为你不能在那里添加布尔参数。相反,您可以以某种不同的方式传递值,如果这适合您(对于像 intbool 这样的原始值,我们也不能重载运算符)。

template<typename T>
struct maybe_const_value {
   T t;
   bool isconst;
};

enum foo { bar = maybe_const_value{256, true} % magicTransform }; 

int main() { return maybe_const_value{265} % magicTransform; }

运算符函数然后可以检查 input.isconst 并使用 input.t 作为实际值。