如何在运行时在 C++ 中创建参数列表以将其传递给模板函数(...,Ts &&... 值),如 InsertOrUpdateMutationBuilder
How create argument list in C++ during runtime to pass this to a template function(..., Ts &&... values) like in InsertOrUpdateMutationBuilder
我想用 C++ 编写 google-cloud-spanner。
我使用的 api-package 来自 https://github.com/googleapis/google-cloud-cpp.
在第 1677ff 行的代码 https://github.com/googleapis/google-cloud-cpp/blob/main/google/cloud/spanner/samples/samples.cc 中,可以看到“InsertOrUpdateMutationBuilder”中的方法“EmplaceRow”,或者从第 1739 行到 1743 行中不是很简单的“MakeInsertOrUpdateMutation”。
正在查看
https://googleapis.dev/cpp/google-cloud-spanner/latest/namespacegoogle_1_1cloud_1_1spanner.html
可以看到“EmplaceRow”和“MakeInsertOrUpdateMutation”的示例代码。
更准确地说,您可以在
上查看“EmplaceRow”示例代码
https://googleapis.dev/cpp/google-cloud-spanner/latest/namespacegoogle_1_1cloud_1_1spanner.html#a3451b640c4ee19df694fa0539047fcdc
和
上的“MakeInsertOrUpdateMutation”示例代码
https://googleapis.dev/cpp/google-cloud-spanner/latest/namespacegoogle_1_1cloud_1_1spanner.html#aced68ba9bc789f44693ad29962fc6ed6
我的问题是:
我如何创建一个变量(!)参数列表以将它们传递到“EmplaceRow”或“MakeInsertOrUpdateMutation”中作为“Ts &&... values”。
而“可变参数列表”意味着这个“列表”(不是std::list)可以以上述方式用作“Ts &&... values”-list.
直到现在我已经搜索了很多解决方案,但没有找到合适的解决方案:
- 两个模板函数,使用 std::tuple 将其元组元素扩展到“Ts &&... 值”列表。
- 两个模板函数,使用 std::array 将其数组元素扩展到“Ts &&... values”列表。
两种解决方案都“不错”但没有用!
我想在运行时处理具有不同列数的不同 table,但是 std::tuple 和 std::array 的大小必须在编译时固定(!)。
因此,无法通过 std::tuple 和 std::array.
解决在运行时创建“Ts &&... values”列表
所以...我如何从 std::vector、std::list 或其他容器类型创建,这些容器类型可以创建、调整大小并填充“spanner::Value”值,“Ts &&... values”-list 将其传递给“EmplaceRow”或“MakeInsertOrUpdateMutation”。
这是我将 std::tuple 扩展为“Ts &&... values”列表的代码:
template <typename Tuple, std::size_t... I>
int myInsrtOrUpdMutBldEmplaceRowBuild_Tup(confDataProc::processConfigData testA,
Tuple const& tuple,
std::index_sequence<I...>)
{
namespace spanner = ::google::cloud::spanner;
//std::cout << "the second 'myInsrtOrUpdMutBldEmplaceRowBuild_Tup'" << std::endl;
auto client = GoClSp::MakeSampleClient(testA.getProjectID(),
testA.getInstanceID(),
testA.getDatabaseID());
auto commit = client.Commit(spanner::Mutations{
spanner::InsertOrUpdateMutationBuilder(
testA.getTableName(),
testA.getColumnNamesOfTable())
.EmplaceRow(std::get<I>(tuple)...)
.Build()});
if (!commit)
{
throw std::runtime_error(commit.status().message());
}
return 0;
}
template <typename Tuple>
int myInsrtOrUpdMutBldEmplaceRowBuild_Tup(confDataProc::processConfigData testA,
Tuple const& tuple)
{
//std::cout << "the first 'myInsrtOrUpdMutBldEmplaceRowBuild_Tup'" << std::endl;
int iRetVal = myInsrtOrUpdMutBldEmplaceRowBuild_Tup(testA,
tuple,
std::make_index_sequence<std::tuple_size<Tuple>::value>());
return iRetVal;
}
此代码有效,但最大的问题是 std::tuple 的大小必须在编译时已知,并且不能在运行时使用变量 size/length 创建。 size/length 在此上下文中是已处理的 table.
的列数
也许解决方案对于其他(更好的)程序员比我更明显,或者可能很难。但是无论如何,我们总是欢迎截取有用的代码或有用的 link。
顺便说一句:
根据我的经验,这与 'classic' 可变参数非常不同。
我无法更改方法“EmplaceRow”或“MakeInsertOrUpdateMutation”的行为 - 如果我想将“Ts &&... 值”列表更改为更简单的“std::vectorspanner::值值".
另一方面:
如果有其他 C++ 函数可以在 cloud-spanner table 中插入或更新 table 行,我不知道,请告诉我。
我“只”需要一个在 C++ 中插入或更新一行 table 的解决方案,我不坚持上述方式。
将 EmplaceRow
替换为 AddRow 就可以了。
您无法在此处以实用的方式将运行时参数转换为模板参数。 (我无法向您展示如何做,但请相信我,这里的计划很糟糕;我只是不说“不可能”,因为我不喜欢说谎。)
我发现 google 的 C++ 文档需要愿意并且能够阅读原始 headers 和源代码。在这里,我找到了定义了 EmplaceRow
的 class 并查找了它的作用或替代方法。
Emplace
在 C++ 术语中的意思是“完美转发到存储”;通常附近有一个不完善的转发方法(例如,push_back
vs emplace_back
),当模板妨碍时。
我想用 C++ 编写 google-cloud-spanner。
我使用的 api-package 来自 https://github.com/googleapis/google-cloud-cpp.
在第 1677ff 行的代码 https://github.com/googleapis/google-cloud-cpp/blob/main/google/cloud/spanner/samples/samples.cc 中,可以看到“InsertOrUpdateMutationBuilder”中的方法“EmplaceRow”,或者从第 1739 行到 1743 行中不是很简单的“MakeInsertOrUpdateMutation”。
正在查看
https://googleapis.dev/cpp/google-cloud-spanner/latest/namespacegoogle_1_1cloud_1_1spanner.html
可以看到“EmplaceRow”和“MakeInsertOrUpdateMutation”的示例代码。
更准确地说,您可以在
上查看“EmplaceRow”示例代码
https://googleapis.dev/cpp/google-cloud-spanner/latest/namespacegoogle_1_1cloud_1_1spanner.html#a3451b640c4ee19df694fa0539047fcdc
和
上的“MakeInsertOrUpdateMutation”示例代码
https://googleapis.dev/cpp/google-cloud-spanner/latest/namespacegoogle_1_1cloud_1_1spanner.html#aced68ba9bc789f44693ad29962fc6ed6
我的问题是:
我如何创建一个变量(!)参数列表以将它们传递到“EmplaceRow”或“MakeInsertOrUpdateMutation”中作为“Ts &&... values”。
而“可变参数列表”意味着这个“列表”(不是std::list)可以以上述方式用作“Ts &&... values”-list.
直到现在我已经搜索了很多解决方案,但没有找到合适的解决方案:
- 两个模板函数,使用 std::tuple 将其元组元素扩展到“Ts &&... 值”列表。
- 两个模板函数,使用 std::array 将其数组元素扩展到“Ts &&... values”列表。
两种解决方案都“不错”但没有用!
我想在运行时处理具有不同列数的不同 table,但是 std::tuple 和 std::array 的大小必须在编译时固定(!)。
因此,无法通过 std::tuple 和 std::array.
所以...我如何从 std::vector、std::list 或其他容器类型创建,这些容器类型可以创建、调整大小并填充“spanner::Value”值,“Ts &&... values”-list 将其传递给“EmplaceRow”或“MakeInsertOrUpdateMutation”。
这是我将 std::tuple 扩展为“Ts &&... values”列表的代码:
template <typename Tuple, std::size_t... I>
int myInsrtOrUpdMutBldEmplaceRowBuild_Tup(confDataProc::processConfigData testA,
Tuple const& tuple,
std::index_sequence<I...>)
{
namespace spanner = ::google::cloud::spanner;
//std::cout << "the second 'myInsrtOrUpdMutBldEmplaceRowBuild_Tup'" << std::endl;
auto client = GoClSp::MakeSampleClient(testA.getProjectID(),
testA.getInstanceID(),
testA.getDatabaseID());
auto commit = client.Commit(spanner::Mutations{
spanner::InsertOrUpdateMutationBuilder(
testA.getTableName(),
testA.getColumnNamesOfTable())
.EmplaceRow(std::get<I>(tuple)...)
.Build()});
if (!commit)
{
throw std::runtime_error(commit.status().message());
}
return 0;
}
template <typename Tuple>
int myInsrtOrUpdMutBldEmplaceRowBuild_Tup(confDataProc::processConfigData testA,
Tuple const& tuple)
{
//std::cout << "the first 'myInsrtOrUpdMutBldEmplaceRowBuild_Tup'" << std::endl;
int iRetVal = myInsrtOrUpdMutBldEmplaceRowBuild_Tup(testA,
tuple,
std::make_index_sequence<std::tuple_size<Tuple>::value>());
return iRetVal;
}
此代码有效,但最大的问题是 std::tuple 的大小必须在编译时已知,并且不能在运行时使用变量 size/length 创建。 size/length 在此上下文中是已处理的 table.
的列数也许解决方案对于其他(更好的)程序员比我更明显,或者可能很难。但是无论如何,我们总是欢迎截取有用的代码或有用的 link。
顺便说一句:
根据我的经验,这与 'classic' 可变参数非常不同。
我无法更改方法“EmplaceRow”或“MakeInsertOrUpdateMutation”的行为 - 如果我想将“Ts &&... 值”列表更改为更简单的“std::vectorspanner::值值".
另一方面:
如果有其他 C++ 函数可以在 cloud-spanner table 中插入或更新 table 行,我不知道,请告诉我。
我“只”需要一个在 C++ 中插入或更新一行 table 的解决方案,我不坚持上述方式。
将 EmplaceRow
替换为 AddRow 就可以了。
您无法在此处以实用的方式将运行时参数转换为模板参数。 (我无法向您展示如何做,但请相信我,这里的计划很糟糕;我只是不说“不可能”,因为我不喜欢说谎。)
我发现 google 的 C++ 文档需要愿意并且能够阅读原始 headers 和源代码。在这里,我找到了定义了 EmplaceRow
的 class 并查找了它的作用或替代方法。
Emplace
在 C++ 术语中的意思是“完美转发到存储”;通常附近有一个不完善的转发方法(例如,push_back
vs emplace_back
),当模板妨碍时。