std::tuple
содержит, среди прочего, следующие конструкторы:
explicit tuple( const Types&... args );
template< class... UTypes >
explicit tuple( UTypes&&... args );
Оба имеют эквивалентные описания в том, что они инициализируют каждый из элементов с соответствующим значением в args
, Разница лишь в том, что во втором параметры передаются.
Из того, что я понял о ссылках на rvalue, я не понимаю, почему требуется первая версия, поскольку во второй версии могут быть переданы те же параметры. Ссылки будут отправлены, и никто не станет мудрее, тем более что нет упоминания о семантике перемещения.
Кто-нибудь может объяснить, что делает оба конструктора необходимыми?
Вот упрощенный пример:
template <typename T>
struct foo
{
foo(const T&);
template <typename U>
foo(U&&);
};
Второй конструктор требует некоторого вывода типа шаблона. Это работает не во всех случаях, например со списками инициализаторов. Следующая инициализация работает, только если доступен первый конструктор:
auto f = foo<std::vector<int>>{ { 1, 2, 3 } };
Это для пересылки ссылок RValue и оптимизировано для построения перемещения. Первая версия используется для lvalues. Смотрите следующую ссылку, чтобы лучше объяснить.
http://thbecker.net/articles/rvalue_references/section_07.html