大括号括起来的初始值设定项列表转换错误
brace-enclosed initializer list conversion error
我有以下旧代码,用于处理 C++、QuantLib 和 Boost 的“较旧”combinations/versions。
在考虑升级到更新版本的想法时,即 C++11、QuantLib >= 1.76、boost >= 1_71 构建现在抛出以下“转换”错误。
我正在使用 [选项] g++ -std=gnu++11
hestonslvmodule.cpp:456:7: warning: narrowing conversion of ‘(QuantLib::FdmHestonGreensFct::Algorithm)greensAlgorithm’ from ‘Quant
Lib::FdmHestonGreensFct::Algorithm’ to ‘QuantLib::Real’ {aka ‘double’} [-Wnarrowing]
456 | greensAlgorithm,
| ^~~~~~~~~~~~~~~
hestonslvmodule.cpp:457:7: error: cannot convert ‘const QuantLib::FdmSquareRootFwdOp::TransformationType’ to ‘const QuantLib::FdmH
estonGreensFct::Algorithm’ in initialization
457 | transformationType,
| ^~~~~~~~~~~~~~~~~~
| |
| const QuantLib::FdmSquareRootFwdOp::TransformationType
hestonslvmodule.cpp:458:7: error: cannot convert ‘const QuantLib::FdmSchemeDesc’ to ‘const QuantLib::FdmSquareRootFwdOp::Transform
ationType’ in initialization
458 | schemeDesc
| ^~~~~~~~~~
| |
| const QuantLib::FdmSchemeDesc
hestonslvmodule.cpp:459:5: error: could not convert ‘<brace-enclosed initializer list>()’ from ‘<brace-enclosed initializer list>’
to ‘const QuantLib::FdmSchemeDesc’
459 | };
| ^
| |
| <brace-enclosed initializer list>
我确实收到了一些关于大括号列表的评论,并且必须拥有“正确的”C++ 版本才能处理这些问题,但我的 C++ 还不够好,无法确定问题到底出在哪里 (这是我 opinion/best 的猜测)代码的哪一部分现在表现得“很有趣”,导致了问题。
FdmSchemeDesc getFdmSchemeDesc(const std::string& schemeDescStr) {
return (schemeDescStr == "ModifiedCraigSneyd") ? FdmSchemeDesc::ModifiedCraigSneyd()
: (schemeDescStr == "CraigSneyd") ? FdmSchemeDesc::CraigSneyd()
: (schemeDescStr == "Hundsdorfer") ? FdmSchemeDesc::Hundsdorfer()
: (schemeDescStr == "ModifiedHundsdorfer") ? FdmSchemeDesc::ModifiedHundsdorfer()
: (schemeDescStr == "ImplicitEuler") ? FdmSchemeDesc::ImplicitEuler()
: (schemeDescStr == "ExplicitEuler") ? FdmSchemeDesc::ExplicitEuler()
: (schemeDescStr == "Douglas") ? FdmSchemeDesc::Douglas()
: (stop("unknown scheme type"), FdmSchemeDesc::ExplicitEuler());
}
最终在这里使用...
class HestonSLVFDMModel {
public:
HestonSLVFDMModel(QuantLib::Date referenceDate,
QuantLib::Date maxDate,
Function localVol,
S4 hestonProcess,
S4 fdmParams) {
if (!fdmParams.is("HestonSLVFDMParams"))
stop("Last parameter needs to be of type HestonSLVFDMParams");
const std::string greensAlgoStr
= as<std::string>(fdmParams.slot("greensAlgorithm"));
const FdmHestonGreensFct::Algorithm greensAlgorithm =
(greensAlgoStr == "Gaussian") ? FdmHestonGreensFct::Gaussian
: (greensAlgoStr == "ZeroCorrelation") ? FdmHestonGreensFct::ZeroCorrelation
: (greensAlgoStr == "SemiAnalytical") ? FdmHestonGreensFct::SemiAnalytical
: (stop("unknown Greens function type"), FdmHestonGreensFct::SemiAnalytical);
const std::string trafoTypeStr
= as<std::string>(fdmParams.slot("transformationType"));
const FdmSquareRootFwdOp::TransformationType transformationType =
(trafoTypeStr == "Plain") ? FdmSquareRootFwdOp::Plain
: (trafoTypeStr == "Power") ? FdmSquareRootFwdOp::Power
: (trafoTypeStr == "Log") ? FdmSquareRootFwdOp::Log
: (stop("unknown transformation type"), FdmSquareRootFwdOp::Log);
const std::string schemeDescStr
= as<std::string>(fdmParams.slot("fdmSchemeType"));
const FdmSchemeDesc schemeDesc = getFdmSchemeDesc(schemeDescStr);
const HestonSLVFokkerPlanckFdmParams params = {
as<unsigned>(fdmParams.slot("xGrid")),
as<unsigned>(fdmParams.slot("vGrid")),
as<unsigned>(fdmParams.slot("tMaxStepsPerYear")),
as<unsigned>(fdmParams.slot("tMinStepsPerYear")),
as<Real>(fdmParams.slot("tStepNumberDecay")),
as<unsigned>(fdmParams.slot("predictionCorrectionSteps")),
as<Real>(fdmParams.slot("x0Density")),
as<Real>(fdmParams.slot("localVolEpsProb")),
as<unsigned>(fdmParams.slot("maxIntegrationIterations")),
as<Real>(fdmParams.slot("vLowerEps")),
as<Real>(fdmParams.slot("vUpperEps")),
as<Real>(fdmParams.slot("vMin")),
as<Real>(fdmParams.slot("v0Density")),
as<Real>(fdmParams.slot("vLowerBoundDensity")),
as<Real>(fdmParams.slot("vUpperBoundDensity")),
as<Real>(fdmParams.slot("leverageFctPropEps")),
greensAlgorithm,
transformationType,
schemeDesc
}; // THIS IS LINE 459
...
所以我的问题是 - 是否有一种优雅或快速的方法来修复处理这些 <brace-enclosed initializer list>()
“转换”的代码?
就像我说的那样,这些对我来说都是“希腊语”,所以我将不胜感激任何有关如何对其应用快速修复的提示(想想我在某处看到只是添加了一组额外的 {}
花括号)?如果我在此处关于错误源的错误路径上,也请随时纠正我?
谢谢
错误是缩小转换,这在统一初始化器中是不允许的。
这是相关的,因为聚合初始化一直存在并且没有那个限制。现在在 C++11 世界中,聚合初始化只是统一初始化的一种形式,具有同上缩小规则。
您应该明确转换相应的值(检查转换是否安全!)
例如
struct X { short i; };
int init = 42;
X x{init}; // not ok
显式转换就可以了:
X x{static_cast<short>(init)}; // ok
我有以下旧代码,用于处理 C++、QuantLib 和 Boost 的“较旧”combinations/versions。
在考虑升级到更新版本的想法时,即 C++11、QuantLib >= 1.76、boost >= 1_71 构建现在抛出以下“转换”错误。
我正在使用 [选项] g++ -std=gnu++11
hestonslvmodule.cpp:456:7: warning: narrowing conversion of ‘(QuantLib::FdmHestonGreensFct::Algorithm)greensAlgorithm’ from ‘Quant
Lib::FdmHestonGreensFct::Algorithm’ to ‘QuantLib::Real’ {aka ‘double’} [-Wnarrowing]
456 | greensAlgorithm,
| ^~~~~~~~~~~~~~~
hestonslvmodule.cpp:457:7: error: cannot convert ‘const QuantLib::FdmSquareRootFwdOp::TransformationType’ to ‘const QuantLib::FdmH
estonGreensFct::Algorithm’ in initialization
457 | transformationType,
| ^~~~~~~~~~~~~~~~~~
| |
| const QuantLib::FdmSquareRootFwdOp::TransformationType
hestonslvmodule.cpp:458:7: error: cannot convert ‘const QuantLib::FdmSchemeDesc’ to ‘const QuantLib::FdmSquareRootFwdOp::Transform
ationType’ in initialization
458 | schemeDesc
| ^~~~~~~~~~
| |
| const QuantLib::FdmSchemeDesc
hestonslvmodule.cpp:459:5: error: could not convert ‘<brace-enclosed initializer list>()’ from ‘<brace-enclosed initializer list>’
to ‘const QuantLib::FdmSchemeDesc’
459 | };
| ^
| |
| <brace-enclosed initializer list>
我确实收到了一些关于大括号列表的评论,并且必须拥有“正确的”C++ 版本才能处理这些问题,但我的 C++ 还不够好,无法确定问题到底出在哪里 (这是我 opinion/best 的猜测)代码的哪一部分现在表现得“很有趣”,导致了问题。
FdmSchemeDesc getFdmSchemeDesc(const std::string& schemeDescStr) {
return (schemeDescStr == "ModifiedCraigSneyd") ? FdmSchemeDesc::ModifiedCraigSneyd()
: (schemeDescStr == "CraigSneyd") ? FdmSchemeDesc::CraigSneyd()
: (schemeDescStr == "Hundsdorfer") ? FdmSchemeDesc::Hundsdorfer()
: (schemeDescStr == "ModifiedHundsdorfer") ? FdmSchemeDesc::ModifiedHundsdorfer()
: (schemeDescStr == "ImplicitEuler") ? FdmSchemeDesc::ImplicitEuler()
: (schemeDescStr == "ExplicitEuler") ? FdmSchemeDesc::ExplicitEuler()
: (schemeDescStr == "Douglas") ? FdmSchemeDesc::Douglas()
: (stop("unknown scheme type"), FdmSchemeDesc::ExplicitEuler());
}
最终在这里使用...
class HestonSLVFDMModel {
public:
HestonSLVFDMModel(QuantLib::Date referenceDate,
QuantLib::Date maxDate,
Function localVol,
S4 hestonProcess,
S4 fdmParams) {
if (!fdmParams.is("HestonSLVFDMParams"))
stop("Last parameter needs to be of type HestonSLVFDMParams");
const std::string greensAlgoStr
= as<std::string>(fdmParams.slot("greensAlgorithm"));
const FdmHestonGreensFct::Algorithm greensAlgorithm =
(greensAlgoStr == "Gaussian") ? FdmHestonGreensFct::Gaussian
: (greensAlgoStr == "ZeroCorrelation") ? FdmHestonGreensFct::ZeroCorrelation
: (greensAlgoStr == "SemiAnalytical") ? FdmHestonGreensFct::SemiAnalytical
: (stop("unknown Greens function type"), FdmHestonGreensFct::SemiAnalytical);
const std::string trafoTypeStr
= as<std::string>(fdmParams.slot("transformationType"));
const FdmSquareRootFwdOp::TransformationType transformationType =
(trafoTypeStr == "Plain") ? FdmSquareRootFwdOp::Plain
: (trafoTypeStr == "Power") ? FdmSquareRootFwdOp::Power
: (trafoTypeStr == "Log") ? FdmSquareRootFwdOp::Log
: (stop("unknown transformation type"), FdmSquareRootFwdOp::Log);
const std::string schemeDescStr
= as<std::string>(fdmParams.slot("fdmSchemeType"));
const FdmSchemeDesc schemeDesc = getFdmSchemeDesc(schemeDescStr);
const HestonSLVFokkerPlanckFdmParams params = {
as<unsigned>(fdmParams.slot("xGrid")),
as<unsigned>(fdmParams.slot("vGrid")),
as<unsigned>(fdmParams.slot("tMaxStepsPerYear")),
as<unsigned>(fdmParams.slot("tMinStepsPerYear")),
as<Real>(fdmParams.slot("tStepNumberDecay")),
as<unsigned>(fdmParams.slot("predictionCorrectionSteps")),
as<Real>(fdmParams.slot("x0Density")),
as<Real>(fdmParams.slot("localVolEpsProb")),
as<unsigned>(fdmParams.slot("maxIntegrationIterations")),
as<Real>(fdmParams.slot("vLowerEps")),
as<Real>(fdmParams.slot("vUpperEps")),
as<Real>(fdmParams.slot("vMin")),
as<Real>(fdmParams.slot("v0Density")),
as<Real>(fdmParams.slot("vLowerBoundDensity")),
as<Real>(fdmParams.slot("vUpperBoundDensity")),
as<Real>(fdmParams.slot("leverageFctPropEps")),
greensAlgorithm,
transformationType,
schemeDesc
}; // THIS IS LINE 459
...
所以我的问题是 - 是否有一种优雅或快速的方法来修复处理这些 <brace-enclosed initializer list>()
“转换”的代码?
就像我说的那样,这些对我来说都是“希腊语”,所以我将不胜感激任何有关如何对其应用快速修复的提示(想想我在某处看到只是添加了一组额外的 {}
花括号)?如果我在此处关于错误源的错误路径上,也请随时纠正我?
谢谢
错误是缩小转换,这在统一初始化器中是不允许的。
这是相关的,因为聚合初始化一直存在并且没有那个限制。现在在 C++11 世界中,聚合初始化只是统一初始化的一种形式,具有同上缩小规则。
您应该明确转换相应的值(检查转换是否安全!)
例如
struct X { short i; };
int init = 42;
X x{init}; // not ok
显式转换就可以了:
X x{static_cast<short>(init)}; // ok