c++ - C++ 模板函数以随机顺序接受参数
问题描述
我正在编写一个 C++ 网络库,并希望主(模板)函数以随机顺序接受参数,以使其更加用户友好,就像CPR库一样。
模板函数将同时接受多达 10 个参数,每个参数都有不同的类型。有没有办法实例化模板以接受参数类型的任何随机顺序,而不是必须手动包含每种可能性的代码?
例如 - 在这种情况下,使用 3 个参数,每个参数都有不同的类型:
.h 文件
namespace foo
{
template <typename T, typename U, typename V> void do(const T& param_a, const U& param_b , const V& param_c);
};
.cpp 文件
template <typename T, typename U, typename V>
void foo::do(const T& param_a, const U& param_b, const V& param_c) {
//do lots of stuff
}
//instantiate to allow random param order
template void foo::do<int, std::string, long>(const int&, const std::string&, const long&);
template void foo::do<int, long, std::string>(const int&, const long&, const std::string&);
template void foo::do<int, std::string, int>(const int&, const std::string&, const int&);
//etc... to cover all possible param orders
解决方案
如果您的目标是匹配给定库的 API 设计,那么最好的学习方法是深入挖掘其源代码并剖析它。
考虑这段代码(我仍然使用 CPR 作为示例,因为您提到它作为参考):
cpr::Session session;
session.SetOption(option1);
session.SetOption(option2);
session.SetOption(option3);
您需要一种可以处理option1
, option2
,的方法...
,无论它们以何种顺序提供。随后的调用SetOption
可以替换为单个SetOptions(option3, option1, option2)
. 因此我们需要一个可变参数 SetOptions
方法:
template<typename Ts...> // important: don't specialize the possible argument types here
void SetOptions(Ts&&... ts)
{ /* do something for each param in ts... */ }
问题是“如何调用参数包SetOption
中的每个项目ts
?”。这是std::initializer_list
. 你可以在这里找到一个简单的例子。
这里的关键是要有一个重载函数,它可以分别处理每个参数类型(例如在 CPR 中使用 SetOptions)。然后,在“permutable”函数中,为每个参数调用重载函数,一次一个(例如在 CPR 中,然后在各个 地方使用)。
不过要注意的一件事是,您可以传递相同类型的多个参数。根据您想要实现的目标,这可能是一个问题,也可能不是。
此外,您可以使用不受支持的参数类型(不匹配任何重载)调用该方法,在这种情况下,错误消息并不总是明确的,具体取决于您使用的编译器。但是,这是您可以使用static_assert
s 克服的问题。
推荐阅读
- r - 每周从 user_id 和 date 查找新的活跃用户
- html - 背景图像调整大小改变了android中的视图
- django - 如何使用 gunicorn 部署 Django + Whitenoise 应用程序?
- tsql - StartDate 和 EndDate 参数基于在另一个下拉参数中选择的日期列
- python - ValueError:预期的 2D 数组,得到了标量数组:array=5.5
- angular - 我如何将查询参数传递给 Angular 应用程序中的服务内的 REST API?
- c# - 如何在发出 GET 请求时防止转义?
- laravel-5.7 - 分页无法通过 ajax 使用新的 php 函数
- ruby - 如何调用一个方法并立即进入它
- indexing - 如何在托管服务器中配置默认根索引