函数的返回类型必须能够在编译时确定。 C++ 是一种静态类型语言。 auto 并不意味着“可能是任何东西”,而是意味着“将在编译时推导出来”。
如果你有一个函数可能需要返回多种类型,你会想要使用std::variant(C++17 中)或boost::variant(C++17 之前的版本,但需要使用 Boost图书馆)。
在您的具体情况下,由于您的某些调用可能不返回任何内容(由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&) {}