Во-первых, вы не можете инициализировать constexpr
членов класса функциями, которые не constexpr
и std::pow
не constepxr
в стандартном C ++ 17. Обходной путь должен объявить их const
. Хотя их нельзя использовать в местах, где требуется время компиляции const
, они неизменны. Традиционный подход заключается в объявлении их в заголовке, который вы при необходимости включаете в исходные файлы. Затем вам нужен один файл реализации, который определяет статические члены const.
Если ваш код требует const или constexpr времени компиляции, ваш единственный вариант - написать свой pow
.
Вот один из способовИнициализируйте статическую константу с помощью функций, которые не constexpr
перед выполнением main (), используя часть вашего вопроса, в которой показана техника:
Создайте заголовок constinit.h, который объявляет класс
// include header guards
// declare the static consts
struct ClassName {
static double DEFAULT_TARGET_TINITIAL_DIGITS_FROM_1; // represents 0.99
static double DEFAULT_TARGET_INITIAL_PBAD; // to be initialized by pow
};
Создайте файл реализации, который инициализирует статику:
#include "constinit.h"
#include <cmath>
double ClassName::DEFAULT_TARGET_TINITIAL_DIGITS_FROM_1{ 2 }; // represents 0.99
double ClassName::DEFAULT_TARGET_INITIAL_PBAD = (1 - std::pow(10, -DEFAULT_TARGET_TINITIAL_DIGITS_FROM_1));
Чтобы использовать статику:
#include <iostream>
#include "constinit.h"
int main()
{
std::cout << ClassName::DEFAULT_TARGET_INITIAL_PBAD << std::endl;
}
Если требуется constexpr
для инициализации времени компиляции, вам нужноопределить свою собственную constexpr
функцию Pow. Это работает в C ++ 17:
#pragma once // or header guards per your preference
constexpr double my_pow(double x, int exp)
{
int sign = 1;
if (exp < 0)
{
sign = -1;
exp = -exp;
}
if (exp == 0)
return x < 0 ? -1.0 : 1.0;
double ret = x;
while (--exp)
ret *= x;
return sign > 0 ? ret : 1.0/ret;
}
class ClassName {
public:
static constexpr double DEFAULT_TARGET_TINITIAL_DIGITS_FROM_1 = 2; // represents 0.99
static constexpr double DEFAULT_TARGET_TFINAL_DIGITS_FROM_0 = 10; // represents 1e-10
static constexpr double DEFAULT_TARGET_INITIAL_PBAD = (1 - my_pow(10, -DEFAULT_TARGET_TINITIAL_DIGITS_FROM_1));
static constexpr double DEFAULT_TARGET_FINAL_PBAD = my_pow(10, -DEFAULT_TARGET_TFINAL_DIGITS_FROM_0);
static constexpr double DEFAULT_ERROR_TOL_DIGITS = 0.9; // as a fraction of digits in the last place from the above.
static constexpr double DEFAULT_SAMPLE_TIME = 1;
// more unrelated code
};