C++ 11变量参数对齐

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列表?

Mar*_*ork 0

最后我决定将其用作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)