c++ - 有没有办法存储模板参数包并在以后重用它?
问题描述
我有很长的参数包。我想知道有没有办法存储参数包并在以后重用它。例如,如果有 2 个模板:
template<class ... Types> struct A {};
template<class ... Types> struct B {};
我有一个专门的类型:
typedef A<int, int, float> A1_t;
是否有任何操作可以让我创建一个使用与 A1_t 相同的参数包的专用类型 B?( B<int, int, float>
)。有什么方法可以<int, int, float>
从 A1_t 检索或存储它吗?
我想获得一个专门的类型 B1_t 而不是创建 B1_t 的对象。
A 和 B 描述了完全不同的概念,所以我不能让 B 嵌套在 A 中。
此外,我还想将参数包提供给专门的功能模板。
template<class ...Ts>
C<Ts...> func1()
{
}
所以我可以直接打电话func1<int, int, float>()
如果我能做这样的事情会很好:
template<typename T>
transform<B, T> func1()
{
}
下一步将与此类似:
template<template<class...Ts> templ>
B<Ts...> func2(Ts ...args)
{
}
所以我可以func2<A1_t>(1, 2, 3.0f)
直接做。
解决方案
像这样的东西?使用基于偏特化的类型转换:
#include<type_traits>
template<template<typename...> class, typename>
struct with_tmpl_args_of;
template<template<typename...> class OtherTmpl, template<typename...> class Tmpl, typename... Args>
struct with_tmpl_args_of<OtherTmpl, Tmpl<Args...>> {
using type = OtherTmpl<Args...>;
};
template<template<typename...> class OtherTmpl, typename T>
using with_tmpl_args_of_t = typename with_tmpl_args_of<OtherTmpl, T>::type;
// example
template<class ... Types> struct A {};
template<class ... Types> struct B {};
using A1_t = A<int, int, float>;
using B1_t = with_tmpl_args_of_t<B, A1_t>;
// test
static_assert(std::is_same_v<B1_t, B<int, int, float>>);
这仅限于不使用非类型模板参数的类模板。遗憾的是,目前没有办法在同一个模板模板参数的参数中定义同时接受类型和非类型模板参数的模板模板参数。
还要注意默认参数。如果' 的默认参数之一与模板列表中的该位置匹配,则这将不使用OtherTmpl
' 的默认参数,并且如果' 的模板列表(包括默认参数)大于s,则将失败。Tmpl
Tmpl
OtherTmpl
关于您编辑中的其他示例:
第二个示例直接使用我上面定义的类型转换:
template<typename T>
with_tmpl_args_of_t<B, T> func1()
{
}
第三个可以这样完成:
template<typename A, typename... Ts>
with_tmpl_args_of_t<B, A> func2(Ts... args)
{
}
它保证返回类型具有与 相同的模板参数A1_t
,但它确实接受所有类型作为参数,即使它们与 的模板参数中的类型不匹配A1_t
。这通常不是问题。如果类型不能转换为正确的类型,您将在尝试转换时遇到错误。
如果您必须采用与 for 函数参数的模板参数中完全相同的类型A1_t
,您可以执行类似(未经测试)的操作:
template<typename T>
struct func_with_tmpl_args_of;
template<template<typename...> class Tmpl, typename... Args>
struct func_with_tmpl_args_of<Tmpl<Args...>> {
template<typename F>
struct inner {
constexpr inner(F f) : f(std::move(f)) {}
constexpr static decltype(auto) operator()(Args... args) const {
return f(std::forward<Args>(args)...);
}
private:
F f;
};
};
// example
template<typename T>
constexpr inline auto func2 = func_with_tmpl_args_of<T>::inner{[](auto... args)
-> with_tmpl_args_of_t<B, T> {
// actual function body
}};
推荐阅读
- joomla - 重定向权限错误Joomla 3
- arrays - 在 Golang 中作为参数的函数数组
- javascript - 对数组的对象进行分组和计数并创建新数组
- c++ - 带有空集的“越界迭代器”
- php - Codeigniter 中的多插入
- google-chrome-extension - Chrome 标签页 ExecuteScript
- ios - UIKit 未发布 UIAccessibility 通知
- python - 如何在tensorflow中使用skip与tf.data.Dataset api或将批处理设置为0
- c# - 滚动时将数据加载到 FlowControl - C#
- javascript - 一张图表,多系列多数据单数据