我正在尝试获取一个用C ++ 17编写的可在OSX(Mojave)上运行的基于Linux的项目。大部分内容都可以编译,直到获得该文件为止ClassName.hpp
::
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-pow(10,-DEFAULT_TARGET_TINITIAL_DIGITS_FROM_1));
static constexpr double DEFAULT_TARGET_FINAL_PBAD = 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
};
编译时,出现以下错误:
error: constexpr variable
'DEFAULT_TARGET_INITIAL_PBAD' must be initialized by a constant expression
...double DEFAULT_TARGET_INITIAL_PBAD = (1-pow(10,-DEFAULT_TARGET_TINITIAL_DIGITS_FROM_1));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ClassName.hpp: note: non-constexpr function 'pow<int, double>'
cannot be used in a constant expression
static constexpr double DEFAULT_TARGET_INITIAL_PBAD = (1-pow(10,-DEFAULT_TARGET_TINITI...
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/math.h:968:1: note:
declared here
pow(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
因此出于某种原因,它可以在Ubuntu和CentOS上运行。我认为这与如何pow
定义有关?但是我不确定如何解决它,或者甚至是问题所在。我也试着删除constexpr
从DEFAULT_TARGET_TINITIAL_DIGITS_FROM_1
和DEFAULT_TARGET_TFINAL_DIGITS_FROM_0
,使它们const
,但仍然会碰到同样的问题。
首先,你不能初始化constexpr
类成员不是函数constexpr
和std::pow
不constepxr
标准的C ++ 17。解决方法是声明它们const
。尽管不能在需要编译时间的地方使用const
它们,但它们是不可变的。传统方法是在标头中声明它们,并根据需要将其包括在源文件中。然后,您需要一个定义静态const成员的实现文件。
如果您的代码需要编译时间const或constexpr,则唯一的选择是编写自己的代码pow
。
这是一种constexpr
使用表示技术的问题的一部分,使用不在执行main()之前的函数来初始化const statics的一种方法:
创建一个标头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
};
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句