1

How can an implementation look like, that wraps around e.g. a std::tuple as a static list of type/value, plus a type (not contained in tuple) to refer to some kind of owner/visitor.

I want to instantiate like

constexpr auto data = data_of<a>(1, 2.0);

Background

The idea is to use a data_of<T>(...) kind of structure to to pass a list of type/data pairs into a bulk function like this.

template <typename... _Ts>
static constexpr void do_bulk_stuff(_Ts&&... _Vs)
{
    // crazy stuff happens here
}
// call it like
do_bulk_stuff
(
    data_of<a>(1, 2.0), 
    data_of<b>(3), 
    data_of<c>(4.0, 5, 6),
    // ...
);

Attempt 1

So far I ended up with a naive (not working) implementation attempt like

template <typename T, typename... Ts>
struct data_of {
    using type = T;
    using data_t = std::tuple<Ts...>;
    data_t data;
    
    constexpr data_of(Ts&&... Vs)
    : data(Vs...)
    {}
};

Goal

My goal is to achieve a result like this data_of<a> instance pseudo code example

{
    // meta
    type = a;
    data_t = std::tuple<int,double>;

    // runtime
    data = [1, 2.0];
}
2
  • 1
    It appears that it cannot deduce Vs in the constructor function. Commented Apr 12, 2022 at 10:50
  • 1
    [off topic] Identifiers that begin with an underscore followed by an uppercase letter are reserved. Commented Apr 12, 2022 at 13:47

1 Answer 1

3

The issue inherent to your attempt is that class template argument deduction is simply not like its function counterpart. There will be no deduction if any of the class template's arguments is explicitly specified. You fail because the trailing pack is always specified (by omission) as empty.

The solution is to shift the burden onto the mechanism that allows you to specify only part of the arguments: function templates.

template <typename T, typename... Ts>
struct data_of_t {
    using type = T;
    using data_t = std::tuple<Ts...>;
    data_t data;
    
    constexpr data_of_t(Ts&&... vs)
    : data(std::forward<Ts>(vs)...)
    {}
};

template<typename T, typename... Ts>
constexpr auto data_of(Ts&&... vs) {
    return data_of_t<T, Ts...>(std::forward<Ts>(vs)...);
}

Now the type of the expression data_of<a>(1, 2.0) has the same "meta" properties you are after.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.