在C 中更改运行时更改操作

Change Operation at runtime in C++

本文关键字:操作 运行时      更新时间:2023-10-16

我手头有一个小问题。假设有一个只有2个操作数的条件,但我想动态操作。

void somFunc()
{
  if(a && b) /*1*/
  {
  }
  else if(a1 && b1) /*2*/
  {
  }
  else if(a || b) /*3*/
  {
  }
  else if(a1 || b1) /*4*/
}


基本上,1和3完全具有相同的参数,其操作类似于2和4。我想将这4个操作降低到2。
我想知道我是否有一种方法可以使 oper Dynamic。认为我们只有2个操作& amp;||
我可以以任何方式使用模板吗?
如果有人想知道为什么我需要这个,那么如果/其他情况,则有n个条件。如果我以某种方式实现了这一目标,我将条件减少一半。

不确定这是否是您的要求,但是您可以写下类似的内容:

enum OPERATION { AND, OR }; 
bool operation(bool a, bool b,OPERATION op) {
    if (op == AND) return a && b;
    return a || b;
}    
void somFunc(OPERATION op)
{
    if(operation(a,b,op)) 
    {
    }
}

或如评论中建议的,使操作要执行一个功能的参数,例如So

template <OPERATION> 
void somFunc(OPERATION op)
{
    if(op(a,b)) 
    {
    }
}

并将其称为此

somFunc( [](bool a, bool b) { return a && b; });
somFunc( [](bool a, bool b) { return a || b; });

您可以使用指针进行效果。

#include <iostream>
#include <functional>

bool oper1(bool a, bool b) {
    return a || b;
}

bool oper2(bool a, bool b) {
    return a && b;
}
int main() {
    bool a = true, b = false;
    auto oper = oper1;
    if (oper(a, b)) {
        std::cout << "ORn";
    }
    oper = oper2;
    if (oper(a, b)) {
        std::cout << "ANDn";
    }
}

首先,您定义所有条件,以后可以通过设置变量来切换条件。

您也可以使用继承和函子:

#include <iostream>
#include <functional>
#include <memory>
class Operator {
public:
    virtual bool eval(bool a, bool b) = 0;
};
class OrOperator : public Operator {
public:
    bool eval(bool a, bool b) {
        return a || b;
    }
};
class AndOperator : public Operator {
public:
    bool eval(bool a, bool b) {
        return a && b;
    }
};
class VariableOperator : public Operator {
public:
    VariableOperator(bool val) : val(val) {}
    bool eval(bool a, bool b) {
        return val;
    }
private:
    bool val;
};
int main() {
    bool a = true, b = false;
    std::unique_ptr<Operator> oper(new OrOperator);
    if (oper->eval(a, b)) {
        std::cout << "ORn";
    }
    oper.reset(new AndOperator);
    if (oper->eval(a, b)) {
        std::cout << "ANDn";
    }
    oper.reset(new VariableOperator(true));
    if (oper->eval(a, b)) {
        std::cout << "VARIABLEn";
    }
}

您可能正在寻找类似的东西:

void somFunc()
{
  std::vector< std::function< bool(bool, bool) > > operators = {
    [](bool a, bool b){ return a && b; },
    [](bool a, bool b){ return a || b; }
  };
  for ( auto& op : operators )
  {
      if ( op( a, b ) )
      {
      }
      else if ( op( a1, b1 ) )
      {
      }
  }
}

您可以添加更多运算符或容易更改参数类型。

您可以使用 CRTP 也可以做到这一点:

#include <iostream>
#include <string>
#include <memory>
template<class T>
class Operation
{
public:
   bool eval(bool a, bool b)
   {
      return this->impl().eval(a,b);
   }
private:
   T& impl() { return static_cast<T&>(*this); }
};
class AndOperation : public Operation<AndOperation>
{
public:
   bool eval(bool a, bool b)
   {
      return a && b;
   }
};
class OrOperation : public Operation<OrOperation>
{
public:
   bool eval(bool a, bool b)
   {
      return a || b;
   }
};
int main()
{
  AndOperation andOp;
  auto anonOp = std::make_unique<OrOperation>();
  std::cout << andOp.eval(true, true) << std::endl;
  std::cout << anonOp->eval(false,false);
}

请参阅 LIVE示例

CRTP 虚拟sashitance 的优点是什么?CRTP是静态多态性的情况。这是一些参考:

编译时间与运行时间多态性在C 优势/缺点

C 中的静态多态性背后的动机是什么?

c :这种编译时多态性的技术是如何调用的?

是什么?

C

中动态(虚拟呼叫)与静态(CRTP)调度的成本

可以使somFunc()成为模板,并接受接受两个参数并返回可以用if进行测试的值的功能。

 #include <functional>    // for binary operations in std
 template<class Operation> void somfunc(Operation oper)
 {
      if (oper(a,b))
      {
            // whatever
      }
 }
 int main()
 {
      somFunc(std::logical_and<int>());
      somFunc(std::logical_or<int>());
      somFunc(std::plus<int>());         //  addition
       //   pass a lambda
      somFunc([](int a, int b) -> int {return a + b;});   // lambda form of addition
 }

在上面,我假设变量ab(已在问题中使用,但未指定的类型)为int类型。