make_tuple с параметрами шаблона не компилируется

Рассмотрим этот код:

#include <tuple>

int main()
{
    int i;
    long k;

    auto tup1 = std::make_tuple<long>(i);   // Compiles
    auto tup2 = std::make_tuple<int>(k);    // Compiles
    auto tup3 = std::make_tuple<int>(i);    // Does not compile
    auto tup4 = std::make_tuple<int>(i+0);  // Compiles
    auto tup5 = std::make_tuple(i);         // Compiles
}

Почему auto tup3 = ... не компилировать? По-видимому, make_tuple<int>(...) хочет ссылку на значение в качестве аргумента; но почему?

(Я использую GCC 6.1.0.)

1 ответ

Решение

std::make_tuple а также std::make_pair предназначены для вывода параметров шаблона (среди прочего, как распаковка справочных упаковщиков). Предоставление их явно является ошибкой.

В данном конкретном случае это происходит потому, что вывод шаблона для rvalues ​​возвращает их тип, аналогичный следующему примеру:

template<typename T>
void foo(T&&);

foo(42); // foo<int>(int&&)
int i{};
foo(i); // foo<int&>(int&) // after reference collapsing

И вот почему make_tuple<int>(...) хочет Rvalue ссылку на свой аргумент.

Если вы хотите форсировать конверсии, все, что вам нужно сказать, это

auto tup1 = std::tuple<long>(i);
Другие вопросы по тегам