C++11 通过函数参数求值顺序将ODBC绑定映射到函数回调

C++11 通过函数参数求值顺序将ODBC绑定映射到函数回调,c++11,visual-c++,C++11,Visual C++,我试图简化一个C/C++代码库,该代码库通过编写各种可变模板从SQL Server调用SQL Server DB语句和/或存储过程。我已经成功地编写了一个doQuery函数,它接受按类型自动绑定到查询的其他参数,例如布尔、双精度、字符串,作为输入或输入/输出参数 当前的问题是: 对于返回结果集的查询,我正在努力生成最佳的简单模板调用 我曾经尝试过元组,但它们在传统的C开发团队中并不受欢迎,我自己也不喜欢它们 因此,我接受一个函数,它用每行的数据调用,用户可以选择以任何形式推送/init{},例如

我试图简化一个C/C++代码库,该代码库通过编写各种可变模板从SQL Server调用SQL Server DB语句和/或存储过程。我已经成功地编写了一个doQuery函数,它接受按类型自动绑定到查询的其他参数,例如布尔、双精度、字符串,作为输入或输入/输出参数

当前的问题是:

对于返回结果集的查询,我正在努力生成最佳的简单模板调用

我曾经尝试过元组,但它们在传统的C开发团队中并不受欢迎,我自己也不喜欢它们

因此,我接受一个函数,它用每行的数据调用,用户可以选择以任何形式推送/init{},例如,推送到捕获的结构向量中。根据回调的签名,我将ODBC的SQLBindCol绑定生成到返回列的绑定信息数组中,复杂度为N

e、 g

[……]

见:和

  • 在带括号的init列表的初始值设定项列表中,初始值设定项子句(包括由包扩展([temp.variadic])产生的任何子句)将按照它们出现的顺序进行计算。也就是说,在初始值设定项列表的逗号分隔列表中,与给定初始值设定项子句相关联的每个值计算和副作用在与任何初始值设定项子句相关联的每个值计算和副作用之前排序。[注:无论初始化的语义如何,此求值顺序都适用;例如,当初始化器列表的元素被解释为构造函数调用的参数时,它适用,即使调用的参数通常没有顺序约束。-结束注]

  • [以上注释在文本中,不是我添加的。]

    您可能正在寻找。该页面上的示例显示了如何使用它来扩展参数包。我在make_integer_序列中没有看到如何将参数包扩展到函数调用中。所以我做了一个递归lambda实现,它构建了一个lambda链,每个递归一个参数,而不生成整数序列。不必要的递归仍然会中断参数类型,例如unique_ptr,它在std::forward上中断,而平面实现对此没有问题。我将向Microsoft记录一个bug,以使迟钝的递归实现成为必要。这不应该是lisp,我很难相信它除了功能之外不会影响性能。我可以发布代码。一种典型的方法是,添加一个助手函数,如
    模板void helper(std::integer_sequence){functor(GetResult(columns,is);}
    。然后将其称为
    helper(std::make_integer_sequence())
    其中
    N
    是希望包扩展到的元素数<当序列
    0,1,…,N-1
    递归构造lambda时,可以增加整数函数参数,使用绑定向量、状态跟踪和任何其他细节捕获。很遗憾不得不去惹麻烦。很容易注意到副作用,只有在没有明显副作用的情况下进行优化时才能重新排序。标准要求它。我看过10年后立即获得标准的高质量编译器的输出。在优化之前,在模板选择的每个级别上使用函数强制转换的lambda递归是一团乱。MSVC是否会对此进行优化?最好修复编译器并避免模板递归。
    integer\u序列
    不依赖递归或副作用。生成的代码将等价于
    functor(GetResult(columns,0),GetResult(columns,1),…,GetResult(columns,N-1))模板void helper(std::integer_sequence){functor(GetResult(columns,is);}
    。然后将其称为
    helper(std::make_integer_sequence())
    其中
    N
    是希望包扩展到的元素数<当序列
    0,1,…,N-1
    递归构造lambda时,可以增加整数函数参数,使用绑定向量、状态跟踪和任何其他细节捕获。很遗憾不得不去惹麻烦。很容易注意到副作用,只有在没有明显副作用的情况下进行优化时才能重新排序。标准要求它。我看过10年后立即获得标准的高质量编译器的输出。在优化之前,在模板选择的每个级别上使用函数强制转换的lambda递归是一团乱。MSVC是否会对此进行优化?最好修复编译器并避免模板递归。
    integer\u序列
    不依赖递归或副作用。生成的代码将等价于
    functor(GetResult(columns,0),GetResult(columns,1),…,GetResult(columns,N-1))这不是你想要的吗?
    
    std::vector<MyStruct> result;
    
    auto functor = [&result](int id, string name, bool isOK, string address) {
      result.push_back(MyStruct{id,name,isOK,address});
    }
    
    c.doQuery(functor, "select id, name, isOK, address from MyTable;" /**/);
    
    template <typename T...>
    InternalFunction(T)
    
    vector<Binding> columns;
    
    int i = 0;
    functor(GetResult<T>(columns, i++)...);
    
    struct OrderedCall
    {
        template <typename F, typename ...Args>
        OrderedCall(F && f, Args &&... args)
        {
            std::forward<F>(f)(std::forward<Args>(args)...);
        }
    };
    
    OrderedCall{functor, GetResult<T>(columns, i++)...};
    
    #include <iostream>
    #include <string>
    
    struct OrderedCall
    {
            template <typename F, typename ...Args>
            OrderedCall(F && f, Args &&... args)
            {
                    std::forward<F>(f)(std::forward<Args>(args)...);
            }
    };
    void foo(int, std::string s, char, bool) {
            int i = 0;
            i++;
    }
    
    int bar() {
            return 10;
    }
    
    template <typename T>
    T echo(T x) {
            std::cout << " " << x;
            return x;
    }
    
    int main(int argc, char**argv) {
            std::string goo = "Goo";
    
            std::cout << "Occurance: " << bar() << " " << goo << " " << 'x' << " " << false;
    
            std::cout << std::endl << "Unordered call:";
            foo(echo(bar()), echo(goo), echo('x'), echo(false));
    
            std::cout << std::endl << "Ordered call:";
            OrderedCall{ foo, echo(bar()), echo(goo), echo('x'), echo(false) };
    
            std::cout << std::endl << "Try in Debug and Release modes. " << std::endl
                    << "Ordered should match Occurance" << std::endl;
    }
    
    Occurance: 10 Goo x 0
    Unordered call: Goo 0 x 10
    Ordered call: 0 x 10 Goo
    Try in Debug and Release modes.
    Ordered should match Occurance