2016-07-29 4 views
3

Я прочитал this, this, this и многие другие ... но ни одна из этих сообщений не отвечает или не применима к моей конкретной проблеме.Конструктор шаблонов Variadic с несколькими пакетами параметров

У меня есть X-структура с VARIADIC конструктором шаблона:

struct X 
{ 
    template<typename... T> 
    X(T... t) { /*...*/ } 
}; 

И у меня есть структура Y, которая содержит два объекта типа X. Я хотел бы определить конструктор шаблонов для Y, что позволяет правильно инициализировать оба члена типа X со списком различных параметров, то есть что-то, что выглядит как следующий код (который, очевидно, не работает):

struct Y 
{ 
    template<typename... U, typename... V> 
    Y(U&&... u, V&&... v)        // this does not work 
     : x1(std::forward(u)...), x2(std::forward(v)...) // this is was I need to do 
     {} 

    X x1, x2; 
}; 

Как мог Я делаю это, используя обертки, кортежи или любые подходящие машины метапрограммирования? Решение C++ 14 приемлемо.

+0

@ πάντα ῥεῖ: Я прошу C++ 14; связанный с вами вопрос может быть подходящим решением для моей проблемы, но ему 2 года! возможно, лучше использовать C++ 14. – shrike

+0

Я не уверен, что C++ 14 сильно изменил процесс распаковки VTP, но хорошо ... –

+0

@ πάντα ῥεῖ: вы не уверены? Я уверен, что C++ 14 добавил некоторые новые интересные функции для распаковки кортежей ... – shrike

ответ

1

Bog-standard index_sequence трюк.

struct Y 
{ 
private: 
    template<typename... U, typename... V, 
      std::size_t... UIs, std::size_t... VIs> 
    Y(std::tuple<U...>&& u, std::tuple<V...>&& v, 
     std::index_sequence<UIs...>, std::index_sequence<VIs...>) 
     : x1(std::get<UIs>(std::move(u))...), 
      x1(std::get<VIs>(std::move(v))...) 
     {} 
public: 
    template<typename... U, typename... V> 
    Y(std::tuple<U...> u, std::tuple<V...> v) 
     : Y(std::move(u), std::move(v), 
      std::index_sequence_for<U...>{}, 
      std::index_sequence_for<V...>{}) 
     {} 

    X x1, x2; 
}; 

В C++ 17, просто используйте make_from_tuple:

struct Y 
{ 
public: 
    template<typename... U, typename... V> 
    Y(std::tuple<U...> u, std::tuple<V...> v) 
     : x1(std::make_from_tuple<X>(std::move(u))), 
      x2(std::make_from_tuple<X>(std::move(v))) 
     {} 

    X x1, x2; 
}; 
+0

Большое спасибо, трюк работает хорошо ... если я не хочу передавать ссылки на внутренние объекты 'x1' & 'x2'; (я пытался использовать' std :: forward_as_tuple() ', но это не сработало.) Есть ли способ изменить свой код, чтобы он мог работать с кортежами ссылок? (Я обновил свой вопрос, чтобы показать идеальную пересылку, в которой я нуждаюсь.) – shrike

+0

Не должно быть необходимости в каких-либо изменениях. –

+0

Правильно! Я ошибся в списке параметров. Ваш трюк отлично подходит для ссылок. Большое спасибо. – shrike

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