如何存储逻辑关系

时间:2012-09-18 09:57:20

标签: c++ logical-operators

我想找出一个自动逻辑关系检查的解决方案。例如,我有一个函数IsGood(),它将从a,b,c得到bool值。在主程序中,有if(a||b)if(b&&c)或{{ 1}},不同的关系。我想用if(g&&!k&&l||!z)替换所有这些,我想让这个函数更通用,它可以处理不同的逻辑关系。

所以我的想法是设置一些ID,这将有助于此函数知道现在需要处理哪些变量,例如,IsGood()得到值k1,k2,k3,但逻辑关系{{1 * {1}}不知道k1,k2,k3之间的IsGood()

所以我想知道如何让||自动获取值之间的关系。将它们存储在数据库中

喜欢:&&首先检查它是否在place1中,所以它查询数据库,结果是:(这就是为什么我不在IsGood()中取参数,它会检索变量它需要从数据库或配置文件,它只需要placeID。)

地点1(地点编号); k1,k2,k3(变量名);真,TRUE,FALSE(值); &&,|| (逻辑关系)。

但我认为这不好......所以,你能给我一些想法吗?非常感谢!我的工作基于C ++。

我想了解一些有关此问题的想法:

a || b&& c,我可以存储信息,如0,1,所以0代表||,1代表&&,所以结构类似于&& b || c .. 。易于控制。

但如何设置(a || b)&& c?我也想找到一种记录这种关系的方法。一个聪明的方法将不胜感激!!感谢。

2 个答案:

答案 0 :(得分:0)

我首先要定义一组适用于给定对象的逻辑操作,例如:

// This is just a simple wrapper for the first argument
template <typename T>
struct FirstOp
{
  FirstOp(T const& v) : _v(v)
  { }

  T const & operator*() const { return _v; }

  T const& _v;
};

template <typename T>
struct AndOp
{
  AndOp(T const& v) : _v(v)
  { }

  T const & operator*() const { return _v; }

  // Then hack the stream operator
  template <typename O>
  O const & operator>>(O const & o) const
  {
    if (o)
      o = o && _v; // assumes T supports safe bool

    return o;
  }

  T const& _v;
};

template <typename T>
struct OrOp
{
  OrOp(T const& v) : _v(v)
  { }

  T const& operator*() const { return _v; }

  // Then hack the stream operator
  template <typename O>
  O const & operator>>(O const & o) const
  {
    if (!o)
      o = o || _v; // assumes T supports safe bool

    return o;
  }

  T const& _v;
};

template <typename Op1>
struct ResultOf
{
  ResultOf(Op1 const& cOp) : _o1(cOp), _r(*_o1)
  { }

  ResultOf const & operator=(bool r) const
  { _r = r; return *this; }

  operator bool() const { return _r; }

  // Then hack the stream operator
  template <typename O>
  ResultOf& operator>>(O& o)
  {
    o >> *this;
    return *this;
  }

  Op1 const& _o1;
  mutable bool _r;
};

然后定义IsGood接受参数,重载以支持更多参数。

template <typename T1, typename T2>
bool IsGood(T1 const& t1, T2 const& t2)
{
  return ResultOf<T1>(t1) >> t2;
}

然后你可以打电话如下。

int main(void)
{
  std::cout << IsGood(FirstOp<int>(0), OrOp<int>(1)) << std::endl;
}

因此,此方法允许您执行的操作是使用该操作包装要用于特定逻辑操作的值,然后将其传递给通用IsGood函数。现在,构造的实际运算符是硬编码的,但是没有什么可以阻止您从文件中读取它,然后构造适当的运算符以传递给IsGood。注意:上面是短路的,因此只会根据需要评估参数(将进行函数调用),但不会计算表达式。您应该能够使用上述方法来制定任意复杂的逻辑关系。

免责声明:这是我对你的问题的有限理解......如果它不合时宜啊......

答案 1 :(得分:0)

这不起作用。周期。

在C ++中,变量具有范围。名称k1可能在不同的地方意味着不同的东西。因此,即使函数IsGood神奇地知道它应该以某种方式访问​​名为k1的变量,它仍然无法找出哪个 k1来自将是哪个范围。

对于C ++程序员来说,这不是什么大问题。他们的解决方案:IsGood(k1),表示:使用当前范围中的 IsGood变量调用k1,而不是另一个。

现在,传递运营商有点困难。你需要lambda:IsGood( [&k1,&k2,&k3](){return (k1&&k2)||k3;} );。这会引用变量k1-3,并将表达式(k1&&k2)||k3;传递给IsGood。或者分为两行:

auto myLambda = [&k1,&k2,&k3](){return (k1&&k2)||k3;} ;
IsGood(myLambda);

同样,这一切都有效,因为您传递了IsGood所需的信息。它不能以任何其他方式得到它。