C++ (可选)下降嵌套结构

C++ (可选)下降嵌套结构,c++,templates,nested,C++,Templates,Nested,假设存在类模板可选: template <class T> class Optional { public: ... bool isPresent(void) const {...} const T& value(void) {...} // throws if !isPresent() ... }; 我正在寻找一种编程习惯用法,它可以提供以下行为而不令人生厌 int get_l_OrDefault(const A& a, int def) {

假设存在类模板
可选

template <class T>
class Optional
{
public:
  ...
  bool isPresent(void) const {...}
  const T& value(void) {...} // throws if !isPresent()
  ...
};
我正在寻找一种编程习惯用法,它可以提供以下行为而不令人生厌

int get_l_OrDefault(const A& a, int def)
{
  if (!a.b_.isPresent()) return def;
  else if (!a.b_.value().c_.isPresent()) return def;
  else if (!a.b_.value().c_.value().d_.isPresent()) return def;
  else return a.b_.value().c_.value().d_.value().l_;
}
给定一个
A,我是否可以定义一些内容,以获取非可选叶字段的路径表示形式和默认值

getValueOrDefault(a.b.j_, 0);
getValueOrDefault(a.b.c.k_, 0);
... etc

你可以这样做

template <typename Class, typename Def, typename M>
Def getValueOrDefault(const Class& c, Def, M m)
{
    return c.*m;
}

template <typename Class, typename Def, typename  M, typename ... Ms>
Def getValueOrDefault(const Class& c, Def def, M m, Ms... ms)
{
    if (c.*m) {
        return getValueOrDefault(*(c.*m), def, ms...);
    } else {
        return def;
    }
}
模板
Def GetValuerDefault(常数等级&c、Def、M)
{
返回c*m;
}
模板
Def GetValuerDefault(常数等级&c、Def Def、M M、Ms…Ms)
{
如果(c.*m){
返回GetValuerDefault(*(c.*m),def,ms.);
}否则{
返回def;
}
}
使用方法:

std::cout << getValueOrDefault(a, 0, &A::b, &B::j) << std::endl;
std::cout << getValueOrDefault(a, 0, &A::b, &B::c, &C::k) << std::endl;

std::cout您可以执行以下操作

template <typename Class, typename Def, typename M>
Def getValueOrDefault(const Class& c, Def, M m)
{
    return c.*m;
}

template <typename Class, typename Def, typename  M, typename ... Ms>
Def getValueOrDefault(const Class& c, Def def, M m, Ms... ms)
{
    if (c.*m) {
        return getValueOrDefault(*(c.*m), def, ms...);
    } else {
        return def;
    }
}
模板
Def GetValuerDefault(常数等级&c、Def、M)
{
返回c*m;
}
模板
Def GetValuerDefault(常数等级&c、Def Def、M M、Ms…Ms)
{
如果(c.*m){
返回GetValuerDefault(*(c.*m),def,ms.);
}否则{
返回def;
}
}
使用方法:

std::cout << getValueOrDefault(a, 0, &A::b, &B::j) << std::endl;
std::cout << getValueOrDefault(a, 0, &A::b, &B::c, &C::k) << std::endl;
std::cout这需要绑定

Bind从a到b取a和函数的可选值或b的可选值,并返回b的可选值

假设我们有一个名为
->*bind*
的操作符,它可以将POINTER理解为成员。然后

auto op_l = a->*bind*&A::b1_->*bind*&B::c1_->*bind*&C::d1_->*bind*&D::l_;
return value_or(op_l,def);
(其中值或采用可选值和默认值)。

这需要绑定

Bind从a到b取a和函数的可选值或b的可选值,并返回b的可选值

假设我们有一个名为
->*bind*
的操作符,它可以将POINTER理解为成员。然后

auto op_l = a->*bind*&A::b1_->*bind*&B::c1_->*bind*&C::d1_->*bind*&D::l_;
return value_or(op_l,def);

(其中值或采用可选值和默认值)。

您需要一些递归的方法来实现它。例如,如果可以为A、B、C、结构使用相同的基类,则可以使用如下内容:

struct Presentable <T> {
  Optional<T> opt;
  virtual int getIntValue(int def) {
    if (opt.isPresent())
     return opt.getValue().getIntValue(def);
    else
     return def;
    }
};

struct A : public Presentable<B>) {
  int i_;
};
...
struct D : Presentable <F> {
   int getIntValue(int) {return l_;}
}
struct-Presentable{
可选选项;
虚拟整数getIntValue(整数定义){
if(opt.isPresent())
返回opt.getValue().getIntValue(def);
其他的
返回def;
}
};
结构A:公共可呈现){
国际组织;
};
...
结构D:可呈现{
int getIntValue(int){return l_;}
}
现在,您可以从链的末端或“def”获取您的价值


这只是可能的变体之一,但在任何情况下,您都可能需要一些基类,或者可以使用指针在结构之间创建父子关系(可选类可以帮助创建父子关系),或者可以使用dynamic cast来执行此操作。

您需要一些递归的方法来执行此操作。例如,如果可以为A、B、C、结构使用相同的基类,则可以使用如下内容:

struct Presentable <T> {
  Optional<T> opt;
  virtual int getIntValue(int def) {
    if (opt.isPresent())
     return opt.getValue().getIntValue(def);
    else
     return def;
    }
};

struct A : public Presentable<B>) {
  int i_;
};
...
struct D : Presentable <F> {
   int getIntValue(int) {return l_;}
}
struct-Presentable{
可选选项;
虚拟整数getIntValue(整数定义){
if(opt.isPresent())
返回opt.getValue().getIntValue(def);
其他的
返回def;
}
};
结构A:公共可呈现){
国际组织;
};
...
结构D:可呈现{
int getIntValue(int){return l_;}
}
现在,您可以从链的末端或“def”获取您的价值


这只是可能的变体之一,但在任何情况下,您都可能需要一些基类,或者您可以使用指针在结构之间创建父子关系(可选类可以帮助创建父子关系),或者您也可以使用dynamic cast来做这件事。

Uh,可能
try{return a.b_uuuUValue().c_UValue().d_UValue().l_U;}catch(…){返回def;}在更多的函数语言中,你所要求的将被称为单元格。我不知道C++中的任何一个单元格库,但这可能会给你一个搜索术语来开始寻找。我认为这应该是使用表达式模板实现的。因为你必须依赖于运算符>。它是不可重载的,但是它可能是可能的,也许是<代码>尝试{return a.b_.value().c_.value().d_.value().l_;}catch(…){return def;}在更多的函数语言中,你所要求的将被称为单元格。我不知道C++的任何单声道库,但这可能会给你一个搜索术语来开始寻找。我认为这应该是使用表达式模板实现的。因为你必须依赖于运算符->。它不能重载,但它可能是可能的。