Mar*_*ork 5 c++ lambda variadic-functions c++11
这是我想要实现的界面:
Statement select("SELECT * FROM People WHERE ID > ? AND ID < ?");
select.execute(1462, 1477, [](int ID, std::string const& person, double item1, float item2){
std::cout << "Got Row:"
<< ID << ", "
<< person << ", "
<< item1 << ", "
<< item2 << "\n";
});
Run Code Online (Sandbox Code Playgroud)
哪里'?' select字符串中的变量1462, 1477在运行时与变量参数列表匹配.
这是类定义:
class Statement
{
public:
Statement(std::string const&);
template<class Action, class ...Args>
void execute(Args... param, Action action);
};
Run Code Online (Sandbox Code Playgroud)
不幸的是,这会产生错误:
test.cpp:133:12:错误:没有匹配的成员函数来调用'
execute'select.execute(1462,1477,[](int ID,std :: string const&person,double item1,float item2){
~~ ~~~ ^ ~~~~~~test.cpp:86:14:注意:候选模板被忽略:无法推断模板参数'Action'void
execute(Args ... param,Action action)
~~~ ^ ~~~~~~生成1个错误.
但是,如果我稍微改变函数定义(下面),它编译得很好.
class Statement
{
public:
Statement(std::string const&);
template<class Action, class ...Args>
void execute(Action action, Args... param);
// ^^^^^^^ Move action to the front.
};
// Also changed the call by moving the lambda to the first argument.
Run Code Online (Sandbox Code Playgroud)
我知道变量参数列表的一些语法糖,但我想把变量参数列表放在第一位.有没有什么技巧可以帮助编译器正确推导var arg列表?
最后我决定将其用作std::tuple参数并隐藏参数扩展:
select.execute(
Bind(1462, 1477),
[](int ID, std::string const& person, double item1, float item2){
std::cout << "Got Row:"
<< ID << ", "
<< person << ", "
<< item1 << ", "
<< item2 << "\n";
});
Run Code Online (Sandbox Code Playgroud)
然后我定义:
template<typename ...Args>
inline std::tuple<Args...> Bind(Args... args) { return std::tuple<Args...>(args...);}
Run Code Online (Sandbox Code Playgroud)
该类被重新定义如下:
class Statement
{
public:
Statement(std::string const&);
template<class Action, class ...Args>
void execute(std::tuple<Args...> const& param, Action action);
};
Run Code Online (Sandbox Code Playgroud)