我定义了一些函数,它们返回类型为void,int,float,float *等(某些类也是如此)。
我的cmd是一个从用户输入的字符串向量。其中第0个位置是函数名称(read_lib,square,open_file),第一个位置是参数(/ path / to / file,number_to_square)等。
auto find_and_execute(vector<string> cmd){
//for(auto x: cmd){cout << x << endl;}
if(cmd.at(0) == "square") {return square(stoi(cmd.at(1)));} // unsigned_int
if(cmd.at(0) == "cube") {return cube(stoi(cmd.at(1)));} // unsigned_int
if(cmd.at(0) == "open_file") {open_file(cmd.at(1));} //void
if(cmd.at(0) == "read_lib") {read_lib(cmd.at(1));} //void
if(cmd.at(0) == "read_verilog") {read_verilog(cmd.at(1));} //void
if(cmd.at(0) == "set_top") {set_top(cmd.at(1));} //void
if(cmd.at(0) == "get_pin") {return get_pin(cmd.at(1));} // Pin Class object takes in cell argument
}
错误:&#39; auto&#39;:&#39; unsigned int&#39;然后&#39; Pin&#39;
编辑:我有另一个问题。我的所有函数都没有将字符串输入作为参数。我可以将字符串转换为整数但是如何将其转换为某些类对象,如Pin / Cell
答案 0 :(得分:9)
必须能够在编译时确定函数的返回类型。 C ++是一种静态类型的语言。 auto
并不意味着&#34;可以是任何东西&#34;,它意味着&#34;将在编译时推断出#34;。
如果你有一个需要潜在返回多种类型的函数,你将要使用std::variant
(在C ++ 17中)或boost::variant
(在C ++ 17之前,但需要使用Boost Library。
在具体情况下,由于您的某些调用无法返回任何内容(由void
划分),因此将此变体放在optional
(也是C ++ 17,或boost::optional
如果预先C ++ 17):
using return_t = std::optional<std::variant<unsigned int, Class>>;
return_t find_and_execute(std::vector<std::string> const& cmd) {
if(cmd.at(0) == "square") {return square(stoi(cmd.at(1)));} // unsigned_int
if(cmd.at(0) == "cube") {return cube(stoi(cmd.at(1)));} // unsigned_int
if(cmd.at(0) == "open_file") {open_file(cmd.at(1)); return {};} //void
if(cmd.at(0) == "read_lib") {read_lib(cmd.at(1)); return {};} //void
if(cmd.at(0) == "read_verilog") {read_verilog(cmd.at(1)); return {};} //void
if(cmd.at(0) == "set_top") {set_top(cmd.at(1)); return {};} //void
if(cmd.at(0) == "get_pin") {return get_pin(cmd.at(1));} // Class object
}
return_t result = find_and_execute({std::string("square"), std::string("13")});
if(result) {//Should always be true
try {
unsigned int & value = std::get<unsigned int>(*result);
} catch (std::bad_variant_access const&) {}
}
result = find_and_execute({std::string("open_file"), std::string("File.txt")});
if(!result) {//Should always be true
/*...*/
}
result = find_and_execute({std::string("get_pin"), std::string("EAX")});
if(result) {//Should always be true
try {
Class & value = std::get<Class>(*result);
} catch (std::bad_variant_access const&) {}
}
@ chris建议的替代版本使用std::monostate
来避免使用std::optional
。根据具体情况,这可能是一个更好的界面。
using return_t = std::variant<std::monostate, unsigned int, Class>;
return_t find_and_execute(std::vector<std::string> const& cmd) {
if(cmd.at(0) == "square") {return square(stoi(cmd.at(1)));} // unsigned_int
if(cmd.at(0) == "cube") {return cube(stoi(cmd.at(1)));} // unsigned_int
if(cmd.at(0) == "open_file") {open_file(cmd.at(1)); return {};} //void
if(cmd.at(0) == "read_lib") {read_lib(cmd.at(1)); return {};} //void
if(cmd.at(0) == "read_verilog") {read_verilog(cmd.at(1)); return {};} //void
if(cmd.at(0) == "set_top") {set_top(cmd.at(1)); return {};} //void
if(cmd.at(0) == "get_pin") {return get_pin(cmd.at(1));} // Class object
}
return_t result = find_and_execute({std::string("square"), std::string("13")});
try {
unsigned int & value = std::get<unsigned int>(result);
} catch (std::bad_variant_access const&) {}
result = find_and_execute({std::string("open_file"), std::string("File.txt")});
//Could query for it if you really needed to
//try {
//std::monostate & value = std::get<std::monostate>(result);
//} catch (std::bad_variant_access const&) {}
result = find_and_execute({std::string("get_pin"), std::string("EAX")});
try {
Class & value = std::get<Class>(*result);
} catch (std::bad_variant_access const&) {}