2013-08-18 2 views
6

std::tuple содержит, среди прочего, следующие конструкторы:Нужны ли все конструкторы std :: tuple?

explicit tuple(const Types&... args); 

template< class... UTypes > 
explicit tuple(UTypes&&... args); 

Оба имеют эквивалентные описания в том, что они Инициализировать каждый из элементов с соответствующим значением в args. Единственное отличие состоит в том, что во втором параметры перенаправляются.

Из того, что я понял о ссылках rvalue, я не понимаю, почему требуется первая версия, так как одни и те же параметры могут быть переданы во вторую версию. Ссылки будут отправлены, и никто не будет более мудрее, особенно если не упоминается семантика перемещения.

Может ли кто-нибудь объяснить, что это такое, что делает необходимым оба конструктора?

+3

Вторая версия SFINAE-д из набора перегрузки, если не все 'UTypes' неявно конвертируются в соответствующих' Types' – jrok

ответ

10

Вот упрощенный пример:

template <typename T> 
struct foo 
{ 
    foo(const T&); 
    template <typename U> 
    foo(U&&); 
}; 

Второй конструктор требует какого-то типа шаблона вывода. Это не работает во всех случаях, например. с списками инициализаторов. Следующая инициализация работает только, если первый конструктор доступен:

auto f = foo<std::vector<int>>{ { 1, 2, 3 } }; 
0

Это для справки экспедирования RValue, и оптимизировано для перемещения конструкции. Первая версия используется для lvalues. См. Следующую ссылку, чтобы лучше объяснить.

http://thbecker.net/articles/rvalue_references/section_07.html

+4

Второй вариант может быть использован для ссылок RValue, а также для ссылок именующих. – nosid

+0

Согласовано, но компилятор сделает лучший выбор во время компиляции для подписи функции, и в этом случае у них есть 2 подписи. Я согласен с вашим ответом, так как это помогает с вычитанием шаблона и требуется по этой причине. – bjackfly