我无法将std::stoll
打包成std::function
。天真的
std::function<std::int64_t(std::string const&)> obj = std::stoll;
失败,因为std::stoll
是两个函数的重载(cppreference没有提及 [在询问时] ),其中一个是std::string
另一个std::wstring
作为第一个参数。那我怎么得到我想要的东西呢?
我知道我可以使用一个调用std::stoll
的lambda,但我正在寻找表单的解决方案
auto parser = ???
std::function<std::int64_t(std::string const&)> obj{parser};
答案 0 :(得分:6)
您可以强制转换函数指针以消除歧义:
function<int64_t(string const&)> obj =
static_cast<int64_t(*)(string const&)>(stoll);
编辑:你还需要绑定默认参数,因为stoll
是一个三参数函数,你试图让它只需要一个参数:
function<int64_t(string const&)> obj =
std::bind(static_cast<int64_t(*)(string const&, size_t*, int)>(stoll),
placeholders::_1, nullptr, 10);
答案 1 :(得分:4)
用仿函数包裹它:
struct StringToLongLong {
long long operator () (const std::string& s) const { return stoll(s); }
long long operator () (const std::wstring& s) const { return stoll(s); }
};
std::function<std::int64_t(std::string const&)> obj = StringToLongLong();
注意:函数可以在函数中本地定义。
如果函数在函数中没有(!)本地类(参见@MSalters评论):
struct StringToLongLong {
template <typename String>
long long operator () (const String& s) const { return stoll(s); }
};
std::function<std::int64_t(std::string const&)> obj = StringToLongLong();
注意:如果函数在函数中本地定义,则成员模板无效。
答案 2 :(得分:0)
这看起来像是重载集的问题。用C ++ 1y编写,因为它保存了decltype
#define OVERLOAD_SET(F) struct {\
template<typename...Args> auto operator()(Args&&...args)const{\
return (F)(std::forward<Args>(args)...);\
}\
}
现在我们可以
static OVERLOAD_SET(std::stoll) os_stroll;
和os_stroll
可以传递给std::function
,它只做正确的事。
如果您愿意,甚至可以启用ADL:
#define ADL_OVERLOAD_SET(NS, F) struct {\
template<typename...Args> auto operator()(Args&&...args)const{\
using NS::F;
return F(std::forward<Args>(args)...);\
}\
}
另一项可选改进:
/* cast to function pointer. Copy paste for each calling convention */\
template<typename R, typename Args...>\
operator R(*)(Args...)() const {\
return [](Args...args){return (F)(std::forward<Args>(args)...);};\
}\
或者对Args...
接受的内容有点严格(如果类型转换,上面将返回一个函数指针。它也可能会执行SFINAE以生成更早的失败)。