简体   繁体   中英

Variadic template - type modifiers

Is it possible to wrap or change the type of variadic template arguments? Eg when giving template arguments int, float, double to return a std::tuple<const int*, const float*, const double*> or a std::tuple<std::unique_ptr<int>, std::unique_ptr<float>, std::unique_ptr<double>> ?

I'm asking because I've got this piece of non-variadic code:

#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);
    }
}

which I would like to make variadic.

Yes, you can define a type trait like this:

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

where V is a template template arguments that accommodate variadic template arguments such as std:variant or std::tuple , and Op is what you want to modify the variadic template arguments Args... .

Then your just need define your own Op s:

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

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

and it will works:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM