c++ - 有没有办法存储模板参数包并在以后重用它?

标签 c++ c++17

我有很长的参数包。我想知道有没有办法存储参数包并在以后重用它。例如,如果有 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的默认参数,如果是 Tmpl 之一的默认参数匹配模板列表中的那个位置,如果 Tmpl 将失败的模板列表(包括默认参数)大于 OtherTmpl s。

关于您编辑中的其他示例:

第二个示例直接使用我上面定义的类型转换:
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 的模板参数中的类型不匹配。 .这通常不是问题。如果类型不能转换为正确的类型,您将在尝试转换时遇到错误。

如果您必须采用与 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
}};

关于c++ - 有没有办法存储模板参数包并在以后重用它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60425301/

相关文章:

c++ - 模板函数类型推导和运算符<<

c++指针操作等同于ReadProcessMemory

c++ - 结构化绑定(bind)声明示例中的 if-with-initializer 格式错误?

c++ - 别名模板或专门的派生类?

c++ - 使用定义相互依赖

c++ - Rcpp - 从矩阵/数据帧列表中提取行

MI的C++虚拟表布局(多重继承)

c++ - 按值排序 std::unordered_map<std::string, std::atomic<unsigned int>>

c++ - “fArray”未在此范围内声明

c++ - 为什么 std::variant 在 GCC 8.5 和 GCC 12.1 上对于 `const char *` 文字的行为不同?