Ich möchte eine Nachschlagetabelle zur Kompilierzeit für eine mathematische Funktion in einem bestimmten Bereich berechnen und dann Werte aus der Tabelle zur Laufzeit abrufen. Mein Code ist wie folgt:consExpr - Funktion kann nicht in einem konstanten Ausdruck verwendet werden
#include <iostream>
#include <cmath>
template<int size>
class LookupTable {
public:
constexpr LookupTable(double xMin, double xMax) : array(), xMin(xMin), xMax(xMax), dx((xMax - xMin)/(size - 1)) {
for(auto i = 0; i < size; ++i)
array[i] = exp(xMin + i * dx);
}
constexpr double operator()(double x) const {
return array[std::min(std::max(static_cast<int>((x - xMin)/dx), 0), size-1)];
}
private:
double array[size];
double xMin;
double xMax;
double dx;
};
int main() {
const double x = 0.5;
constexpr LookupTable<10000> table(0.0, 1.0);
std::cout << "f(x) = " << table(x) << std::endl; // evaluated at compile time ?
std::cout << "f(x) = " << LookupTable<10000>(0.0, 1.0)(x) << std::endl; // evaluated at run time ?
return 0;
}
Der Code kompiliert und läuft auf gcc 5.1 und höher, aber nicht auf Clang 3.8. Clangs Fehlermeldungen sind: constexpr Variable 'Tabelle' muss durch einen konstanten Ausdruck initialisiert werden und non-constexpr Funktion 'exp' kann nicht in einem konstanten Ausdruck verwendet werden.
Wenn ich die constexpr in entfernen:
constexpr LookupTable<10000> table(0.0, 1.0);
dann kompiliert den Code und läuft auf Clang auch.
Meine Fragen sind:
- Was ist die Bedeutung der Fehlermeldung „Funktion‚exp‘in einem konstanten Ausdruck verwendet werden kann, nicht“ ist? Und gibt es einen Workaround?
- Bedeutet das, wenn ich LookupTable < 10000 deklariere> Tabelle (0.0, 1.0); Ohne den consExpr, dann finden die Tabellenvorberechnungen zur Laufzeit statt? Ich verwende ein Online-Kompilierungstool, daher habe ich keine Option, den Code jetzt zu benchmarken.
- Ich möchte den Code verallgemeinern und die mathematische Funktion templatisieren. Es funktioniert gut mit Funktoren, aber ist es möglich, Lambdas zu verwenden?
Dank