[英]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.