python - 将Python返回的类型转换为C++

标签 python c++ code-translation

我继承了Python中的一些代码以转换为C++。 Python代码基于其他函数返回的错误代码引发异常。 Python代码使用称为errors(...)的实用程序函数,该函数包含创建字典以将错误代码映射到异常。它返回异常的类型,并且调用代码使用其自己的消息将其实例化。

class BaseError(Exception):
    pass

class Error1(BaseError):
    pass

class Error2(BaseError):
    pass

def errors(code):
    errors_ = {
        1: BaseError,
        2: Error1,
        3: Error2
    }

    try:
        return errors_[code]
    except KeyError:
        return errors_[1]

def ReturnAnError():
    # Oops an error!
    return 2

try:
    val = ReturnAnError()
    if(val):
        raise errors(val)('{} Failed'.format("Example Failed"))
except BaseError as ex:
    print(ex)
我最初的想法是走一条简单的道路,将Python的errors(code)函数重新定义为c++中的void errors(uint8_t code, const char * msg),然后做出一条选择语句,该语句本身将引发异常。
是否存在更优雅或更简洁的解决方案来直接翻译此代码?特别是在C++中raise errors(val)('{} Failed'.format("Example Failed"))最直接的翻译是什么?

最佳答案

如果我直接用C++翻译您的代码:

#include <iostream>
#include <string>
#include <map>

class BaseError {
  public:
    BaseError(std::string s) : msg(s) {}
    virtual ~BaseError() {} // useless because inherited classes do not have attribute to delete
    friend std::ostream & operator<<(std::ostream & out, const BaseError & e) {
       out << e.msg;
       return out;
    }
    static BaseError * mk(std::string s) { return new BaseError(s); }
  private:
    std::string msg;
};

class Error1 : public BaseError {
  public:
    Error1(std::string s) : BaseError(s) {}
    static BaseError * mk(std::string s) { return new Error1(s); }
};

class Error2 : public Error1 {
  public:
    Error2(std::string s) : Error1(s) {}
    static BaseError * mk(std::string s) { return new Error2(s); }
};

typedef BaseError * (*fmk)(std::string);

fmk errors(int code) 
{
  const static std::map<int, fmk> error = {
       {1, &BaseError::mk},
       {2, &Error1::mk},
       {3, &Error2::mk}
  };
  std::map<int, fmk>::const_iterator it = error.find(code);
  
  return ((it == error.end()) ? error.find(1) : it)->second;
}

int ReturnAnError()
{
  // Oops an error!
  return 2;
}


int main()
{
  try {
    int val = ReturnAnError();
  
    if (val)
      throw (errors(val))("blah blah");
  }
  catch (BaseError * ex) {
      std::cout << *ex << std::endl;
      delete ex;
  }
}    
编译与执行:
pi@raspberrypi:/tmp $ g++ c0.cc
pi@raspberrypi:/tmp $ ./a.out
blah blah
pi@raspberrypi:/tmp $ 
关于函数错误:
  • Python词典可以翻译成C++ std::map
  • 与Python相反,我无法在std::map中输入每个类的构造函数的地址,这就是为什么我对每个类使用静态操作mk的原因。
  • 为避免每次调用错误都创建std::map,我定义了错误static(和const明确表示我不想对其进行修改),但这是一种优化,并非强制性的。
  • 在Python中非常频繁地使用异常,在C++中很少使用这种情况,这就是为什么我使用迭代器来知道代码是否为已知键并进行测试的原因。

  • 为了能够打印类的实例,我重载了operator<<,无论如何不允许检查程序创建了Error1,甚至我将代码更改为:
      try {
        int val = ReturnAnError();
      
        if (val)
          throw (errors(val))("blah blah");
      }
      catch (Error2 * ex) {
          std::cout << "err2" << *ex << std::endl;
          delete ex;
      }
      catch (Error1 * ex) {
          std::cout << "err1" << *ex << std::endl;
          delete ex;
      }
      catch (BaseError * ex) {
          std::cout << *ex << std::endl;
          delete ex;
      }
    
    执行的代码将是catch (BaseError * ex) {...}如果我做 :
      try {
        int val = ReturnAnError();
      
        if (val)
          throw *(errors(val))("blah blah");
      }
      catch (Error2 & ex) {
          std::cout << "err2" << ex << std::endl;
      }
      catch (Error1 & ex) {
          std::cout << "err1" << ex << std::endl;
      }
      catch (BaseError & ex) {
          std::cout << ex << std::endl;
      }
    
    再次执行的代码将是catch (BaseError & ex) {...}(并且我创建了内存泄漏)。
    因此,在进行绘画时需要virtual操作来区分类,例如:
    #include <iostream>
    #include <string>
    #include <map>
    
    class BaseError {
      public:
        BaseError(std::string s) : msg(s) {}
        virtual ~BaseError() {} // useless because inherited classes do not have attribute to delete
        virtual void print(std::ostream & out) const { out << msg; }
        static BaseError * mk(std::string s) { return new BaseError(s); }
      private:
        std::string msg;
    };
    
    class Error1 : public BaseError {
      public:
        Error1(std::string s) : BaseError(s) {}
        virtual void print(std::ostream & out) const { 
          out << "error1 ";
          BaseError::print(out);
        }
        static BaseError * mk(std::string s) { return new Error1(s); }
    };
    
    class Error2 : public Error1 {
      public:
        Error2(std::string s) : Error1(s) {}
        virtual void print(std::ostream & out) const { 
          out << "error2 ";
          BaseError::print(out);
        }
        static BaseError * mk(std::string s) { return new Error2(s); }
    };
    
    typedef BaseError * (*fmk)(std::string);
    
    fmk errors(int code) 
    {
      const static std::map<int, fmk> error = {
           {1, &BaseError::mk},
           {2, &Error1::mk},
           {3, &Error2::mk}
      };
      std::map<int, fmk>::const_iterator it = error.find(code);
      
      return ((it == error.end()) ? error.find(1) : it)->second;
    }
    
    int ReturnAnError()
    {
      // Oops an error!
      return 2;
    }
    
    
    int main()
    {
      try {
        int val = ReturnAnError();
      
        if (val)
          throw (errors(val))("blah blah");
      }
      catch (BaseError * ex) {
          ex->print(std::cout);
          std::cout << std::endl;
          delete ex;
      }
    }    
    
    编译与执行:
    pi@raspberrypi:/tmp $ g++ c.cc
    pi@raspberrypi:/tmp $ ./a.out
    error1 blah blah
    pi@raspberrypi:/tmp $ 
    

    Is there a more elegant or concise solution


    坦率地说,这至少不够简洁,但是您的Python代码却不太好;-)

    关于python - 将Python返回的类型转换为C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63251830/

    相关文章:

    python - 在绘图中显示 Y 轴网格线

    c# - 自动将简单的 C++ 代码转换为 C#

    python - readline() 在读取文本文件时如何在幕后工作?

    c++ - 具有静态成员的静态结构

    c++ - 如何使用 unique_ptr<double[]> 为类设置析构函数。该实例由 make_unique() 创建

    c++ - 为什么我的程序继续给我堆缓冲区溢出,即使我没有越界或覆盖任何值

    Ruby 中的 JavaScript

    java - 我怎样才能将这段代码转换成 Racket /方案

    python - 在 python 中使用类型提示悬挂缩进的适当缩进级别是多少?

    python - Pandas 条件映射/填充/替换