可变参数模板-类型修饰符

时间:2020-09-18 05:29:21

标签: c++ visual-c++ c++20

是否可以包装或更改可变参数模板参数的类型?例如。给模板参数int, float, double返回std::tuple<const int*, const float*, const double*>std::tuple<std::unique_ptr<int>, std::unique_ptr<float>, std::unique_ptr<double>>时是什么?

我问是因为我有这段非可变代码:

#pragma once

#include <Variant>

namespace fw::variant {

    /*- Returns a variant with a pointer to the value of vFrom.*/
    template<typename Arg1, typename Arg2>
    std::variant<Arg1*, Arg2*> GetPointerVariant(std::variant<Arg1, Arg2>& vFrom) {
        if (std::holds_alternative<Arg1>(vFrom)) {
            return &std::get<Arg1>(vFrom);
        }
        return &std::get<Arg2>(vFrom);
    }

    /*- Returns a variant with a pointer to the value of vFrom.*/
    template<typename Arg1, typename Arg2>
    const std::variant<const std::remove_const_t<Arg1>*, const std::remove_const_t<Arg2>*> GetPointerVariant(const std::variant<Arg1, Arg2>& vFrom) {
        if (std::holds_alternative<Arg1>(vFrom)) {
            return &std::get<Arg1>(vFrom);
        }
        return &std::get<Arg2>(vFrom);
    }
}

我想使其可变。

1 个答案:

答案 0 :(得分:2)

是的,您可以这样定义类型特征:

template <
  template <typename...> typename V, 
  template <typename> typename Op,
  typename... Args
>
struct modify {
  using type = V<typename Op<Args>::type...>;
};

其中V是模板模板参数,可容纳可变模板参数,例如std:variantstd::tuple, 而Op是您要修改可变参数模板参数Args...的内容。

然后,您只需定义自己的Op

template <typename T>
struct Op1 { using type = const T*; };

template <typename T>
struct Op2 { using type = std::unique_ptr<T>; };

它将起作用:

static_assert(std::is_same_v<
  std::tuple<const int*, const float*, const double*>, 
  modify<std::tuple, Op1, int, float, double>::type
>);
static_assert(std::is_same_v<
  std::variant<std::unique_ptr<int>, std::unique_ptr<float>, std::unique_ptr<double>>,
  modify<std::variant, Op2, int, float, double>::type
>);

Demo.