大括号括起来的初始值设定项列表转换错误

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