[英]Return a std::function with auto return type
我想創建一個仿函數來將 std::string 轉換為不同的類型。
std::function<auto(const std::string)> create(const std::string &type)
{
if(type=="int") {
return [&](const std::string &value){return std::stoi(value);}
} else if(type=="float") {
return [&](const std::string &value){return std::stof(value);}
} else {
throw std::runtime_error("");
}
}
但似乎我們不能在這里使用auto作為std::function的返回類型。
有人可以建議一種方法嗎?
對於一個 function 或一個 function 模板的實例化,返回類型必須相同且固定。 您可以將 function 模板制作為
template <typename R>
std::function<R(const std::string&)> create()
{
if(std::is_same<R, int>::value) {
return [](const std::string &value){return std::stoi(value);};
} else if(std::is_same<R, float>::value) {
return [](const std::string &value){return std::stof(value);};
} else {
throw std::runtime_error("");
}
}
然后像使用它
auto f_int = create<int>();
auto f_float = create<float>();
由於 C++17 您可以使用constexpr if ,因此在編譯時將丟棄不必要的語句。
template <typename R>
std::function<R(const std::string&)> create()
{
if constexpr (std::is_same_v<R, int>) {
return [](const std::string &value){return std::stoi(value);};
} else if constexpr (std::is_same_v<R, float>) {
return [](const std::string &value){return std::stof(value);};
} else {
throw std::runtime_error("");
}
}
順便說一句:作為返回類型, std::function
的參數應該是const std::string&
。 而 lambda 似乎不需要捕獲任何東西。
BTW2:根據您使用返回值的方式,直接返回 lambda 而不是將其包裝到std::function
中也可能就足夠了。
template <typename R>
auto create()
{
if constexpr (std::is_same_v<R, int>) {
return [](const std::string &value){return std::stoi(value);};
} else if constexpr (std::is_same_v<R, float>) {
return [](const std::string &value){return std::stof(value);};
} else {
throw std::runtime_error("");
}
}
我認為不可能在std::function
中進行自動返回類型扣除。
如果您需要存儲調用std::sto*
function 的 lambda/仿函數,我想出了一些替代方案。 只需自己創建一個模板並用它替換auto
。 這允許您刪除const std::string&
類型參數。
#include <type_traits> // for std::is_same
template <typename T = int>
constexpr std::function<T(const std::string)> create()
{
if (std::is_same<T, int>::value)
{ return [&](const std::string &value) { return std::stoi(value); }; }
if (std::is_same<T, float>::value)
{ return [&](const std::string &value) { return std::stof(value); }; }
throw std::runtime_error("");
}
或者您可以自己創建一個函子 class。
#include <type_traits> // for std::is_same
template <typename T = int>
struct Functor {
T operator()(const std::string& input) {
if (std::is_same<T, int>::value) { return std::stoi(input); };
if (std::is_same<T, float>::value) { return std::stof(input); };
throw std::runtime_error("");
}
};
以上用途。
int main() {
auto f_i = create();
auto f_f = create<float>();
f_i("42"); // returns an int
f_f("3.14"); // returns a float
Functor fo_i;
Functor<float> fo_f;
fo_i("42"); // returns an int
fo_f("3.14"); // returns a float
}
我建議簡單地調用正確的數字轉換 function 而不是存儲調用std::sto*
的 lambda/functor 會是更好的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.