大括号括起来的初始值设定项列表转换错误
Posted
技术标签:
【中文标题】大括号括起来的初始值设定项列表转换错误【英文标题】:brace-enclosed initializer list conversion error 【发布时间】:2021-11-21 14:40:36 【问题描述】:我有以下旧代码,这些旧代码用于处理 C++、QuantLib 和 Boost 的“旧”组合/版本。 在考虑升级到新版本(即 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>
我确实在大括号列表中找到了一些 cmets,并且必须拥有“正确”的 C++ 版本才能应对这些问题,但我的 C++ 还不足以了解问题可能出在哪里(这是我的意见/最佳猜测)代码的哪一部分现在表现得“有趣”,导致了问题。
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>()
“转换”方面是否有一种优雅或快速的方法来修复代码?
就像我说的那样,这些都是“对我来说是希腊语”,所以我会很感激任何关于如何对其应用快速修复的提示(我想我在某处看到了额外的一组 大括号被添加)?如果我在此处的错误源方面走错了路,还可以随时纠正我吗?
谢谢
【问题讨论】:
请发minimal reproducible example 可悲的是,这超出了我在这里所能适应的范围(一个 SO 问题)......我知道我通常会尝试将其减少为 reprex,但代码库是一个庞然大物,我是不熟悉 1. 代码(我继承)和 2.params
初始化器列表中缺少一个值(属性),因为类型 transformationType
试图分配给与之前的值greensAlgorithm
相同。
minimal reproducible example (MRE) 的美妙之处在于它很小。获取您的代码并备份它。然后一点一点地去掉重现问题所不需要的一切。通常,您可以将 MRE 简化为几行代码。 MRE 的真正美妙之处在于您很少需要走那么远。通常,当您减少错误周围其他代码的噪音时,错误会变得很明显,因此您停止并修复错误。如果您遇到无法删除任何内容而不删除错误的地步,请编辑问题并粘贴您剩下的内容。
如果您在提问过程的早期构建 MRE,那么您将永远不必点击发布按钮。
【参考方案1】:
错误是缩小转换,这在统一初始化程序中是不允许的。
这是相关的,因为聚合初始化一直存在并且没有那个限制。现在在 C++11 世界中,聚合初始化只是统一初始化的一种形式,还有缩窄规则。
您应该显式转换相应的值(检查转换是否安全!)
例如
struct X short i; ;
int init = 42;
X xinit; // not ok
显式转换就可以了:
X xstatic_cast<short>(init); // ok
【讨论】:
我知道有很多问题要问,但是您能否指出/显示我上面代码中值的(单个)示例转换?您认为(我的猜测)显式转换“schemeDesc”就足够了,还是其他的? 有很多问题要问(看到您有很多依赖项和未显示的代码)。好消息是:编译器已经准确地告诉你哪些。您可以一一拿下——无需猜测(尽管预测可能会提高您的速度)。另外,请注意,如果您正在调用常规构造函数,只需使用()
语法而不是
语法会使缩小行为回到旧规则。以上是关于大括号括起来的初始值设定项列表转换错误的主要内容,如果未能解决你的问题,请参考以下文章