C++11 通过函数参数求值顺序将ODBC绑定映射到函数回调
我试图简化一个C/C++代码库,该代码库通过编写各种可变模板从SQL Server调用SQL Server DB语句和/或存储过程。我已经成功地编写了一个doQuery函数,它接受按类型自动绑定到查询的其他参数,例如布尔、双精度、字符串,作为输入或输入/输出参数 当前的问题是: 对于返回结果集的查询,我正在努力生成最佳的简单模板调用 我曾经尝试过元组,但它们在传统的C开发团队中并不受欢迎,我自己也不喜欢它们 因此,我接受一个函数,它用每行的数据调用,用户可以选择以任何形式推送/init{},例如,推送到捕获的结构向量中。根据回调的签名,我将ODBC的SQLBindCol绑定生成到返回列的绑定信息数组中,复杂度为N e、 g [……] 见:和C++11 通过函数参数求值顺序将ODBC绑定映射到函数回调,c++11,visual-c++,C++11,Visual C++,我试图简化一个C/C++代码库,该代码库通过编写各种可变模板从SQL Server调用SQL Server DB语句和/或存储过程。我已经成功地编写了一个doQuery函数,它接受按类型自动绑定到查询的其他参数,例如布尔、双精度、字符串,作为输入或输入/输出参数 当前的问题是: 对于返回结果集的查询,我正在努力生成最佳的简单模板调用 我曾经尝试过元组,但它们在传统的C开发团队中并不受欢迎,我自己也不喜欢它们 因此,我接受一个函数,它用每行的数据调用,用户可以选择以任何形式推送/init{},例如
[以上注释在文本中,不是我添加的。]您可能正在寻找。该页面上的示例显示了如何使用它来扩展参数包。我在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))这不是你想要的吗?你可能在找。该页面上的示例显示了如何使用它来扩展参数包。我在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))代码>这不是你想要的吗?
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