Python返回类型转换为C++ 我继承了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 Error Script函数重新定义为ValeError Surn8t代码,C++中的const char *MSG,然后选择一个SLECT语句,该语句将抛出异常本身。

Python返回类型转换为C++ 我继承了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 Error Script函数重新定义为ValeError Surn8t代码,C++中的const char *MSG,然后选择一个SLECT语句,该语句将抛出异常本身。,python,c++,code-translation,Python,C++,Code Translation,是否有更优雅或简洁的解决方案来直接翻译此代码?特别是,在C++中,如果我直接在C++中翻译你的代码:< /p>,那么在“c++?< /p> < p>中,Falm错误的最直接的翻译是{{}失败”。 #include <iostream> #include <string> #include <map> class BaseError { public: BaseError(std::string s) : msg(s) {} virtual

是否有更优雅或简洁的解决方案来直接翻译此代码?特别是,在C++中,如果我直接在C++中翻译你的代码:< /p>,那么在“c++?< /p> < p>中,Falm错误的最直接的翻译是{{}失败”。
#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;
  }
}    
关于函数错误:

Python字典可以翻译成C++ STD::MAP/P> 我知道,与Python相反,我不能将每个类的构造函数的地址放入std::map中,这就是为什么我对每个类使用静态操作mk

为了避免每次调用错误时都创建std::map,我定义了error static和const,以明确表示我不想修改它,但这是一种优化,不是强制性的

Python中的异常非常有用,这在C++中的情况就更少了,这就是为什么我使用迭代器来知道代码是已知的密钥的原因,并且我测试它。
为了能够打印我重载的类的实例,操作符一个函数,每个参数的名称和类型完全相同,不能有两个返回类型。因此,不允许错误返回不同类型的异常。i、 e.错误无法准确翻译

但是对于raiseerrorsval…,一种简单的方法是在错误中抛出异常。示例代码:

#include <string>
class BaseError {
public:
    std::string s;
    BaseError(const std::string &_s):s(_s){}
};
class Error1 : public BaseError {
public:
    Error1(const std::string &s):BaseError(s){}
};
class Error2 : public BaseError {
public:
    Error2(const std::string &s):BaseError(s){}
};

void errors(int val, const std::string &s)
{
    switch(val)
    {
    case 1:
        throw BaseError(s);
    case 2:
        throw Error1(s);
    case 3:
        throw Error2(s);
    default:
        throw BaseError(s);
    }
}
class errors {
public:
    int val;
    std::string s;
    errors(int _val, const std::string _s): val(_val), s(_s){}
    void raise()
    {
        switch(val)
        {
        case 1:
            throw BaseError(s);
        case 2:
            throw Error1(s);
        case 3:
            throw Error2(s);
        default:
            throw BaseError(s);
        }
    }
};

您可以在错误中抛出异常,而不是从错误中返回对象。这似乎并不比只将类型添加到BaseError中要好。@yao99您可以更明确一些,我确实理解您的意思,以及为什么python代码中的错误可以由不同的catch段处理,但指向BaseError的指针不能。这似乎是为什么在Python代码中使用错误的原因。@ YA99是的,但这与Python代码不同,可以在Python中进行相同的简化,这样做与标题转换为C++的Python返回类型不兼容。
  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;
  }
#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 $ 
#include <string>
class BaseError {
public:
    std::string s;
    BaseError(const std::string &_s):s(_s){}
};
class Error1 : public BaseError {
public:
    Error1(const std::string &s):BaseError(s){}
};
class Error2 : public BaseError {
public:
    Error2(const std::string &s):BaseError(s){}
};

void errors(int val, const std::string &s)
{
    switch(val)
    {
    case 1:
        throw BaseError(s);
    case 2:
        throw Error1(s);
    case 3:
        throw Error2(s);
    default:
        throw BaseError(s);
    }
}
class errors {
public:
    int val;
    std::string s;
    errors(int _val, const std::string _s): val(_val), s(_s){}
    void raise()
    {
        switch(val)
        {
        case 1:
            throw BaseError(s);
        case 2:
            throw Error1(s);
        case 3:
            throw Error2(s);
        default:
            throw BaseError(s);
        }
    }
};