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