2017-01-10 7 views
4

Сегодня я пытаюсь создать кортеж немного конкретным (для меня как минимум) и во время компиляции.Создайте кортеж с переменным типом завернутый

У меня есть некоторая базовая-структура, скажу:

struct Foo1 { int data; }; 
struct Foo2 { int data; }; 
struct Foo3 { int data; }; 

И еще один-структуру, но с некоторым шаблоном материалом:

template < typename T, 
      size_t Size > 
struct Metadata { 

    using type = T; 

    std::bitset<Size> bitset; 
}; 

Так что теперь я хочу создать такой кортеж:

constexpr std::tuple<Metadata<Foo1, 3>, Metadata<Foo2, 3>, Metadata<Foo3, 3>> test { {0}, {0}, {0}}; 

Но автоматическим способом больше нравится:

template < typename ... Ts > 
constexpr auto make_metadata() { 

    return std::tuple<Metadata<Foo1, sizeof...(Ts)>, 
        Metadata<Foo2, sizeof...(Ts)>, 
        Metadata<Foo3, sizeof...(Ts)>>{{0},{0},{0}}; 
} 

Ну, последний код далеко не хорош, поэтому я хотел бы иметь что-то подобное, но автоматически. Возможно, с tuple_cat и сгибанием выражения, но я немного потерял. Так что если кто-то знает ответ :)

ответ

3

Вы можете использовать ... означает несколько вещей в одном выражении. В этом случае, вы хотите расширить Ts как сразу и не сразу:

template <class... Ts> 
constexpr auto make_metadata() 
{ 
    return std::make_tuple(Metadata<Ts, sizeof...(Ts)>{0}...); 
} 

Кроме того, вы не бы написать все на одной строке, если это делает его более ясным для вас, чтобы написать его в этом путь:

template <class... Ts> 
constexpr auto make_metadata() 
{ 
    constexpr size_t N = sizeof...(Ts); 
    return std::make_tuple(Metadata<Ts, N>{0}...); 
} 
+0

Кажется, что с C++ 17 Мне не нужно явно указывать std :: make_tuple. Но спасибо вам и Гийому в любом случае :) –

+0

@MathieuVanNevel Конечно, вы сможете сохранить 5 символов и просто написать 'std :: tuple (...)'. – Barry

2

Простой VARIADIC расширение шаблон с std::make_tuple будет достаточно:

template <typename... Ts> 
constexpr auto make_metadata() { 
    return std::make_tuple(Metadata<Ts, sizeof...(Ts)>{0}...); 
} 
1

Ниже следует делать то, что вы хотите:

template <typename T> struct tag {}; 

template <typename ... Ts> 
constexpr auto make_metadata() { 

    return std::tuple<Metadata<Ts, sizeof...(Ts)>...>{{(tag<Ts>{}, 0)}...}; 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^