Рассмотрим эту простую функцию
template
auto mkVector(U&& x0)
{
return std::vector{std::forward(x0)};
}
и 4 возможных варианта использования, когда аргументом является либо значение l, либо значение r, а тип либо указывается неявно, либо выводится из аргументов:
const string lvalue("hello");
// type inferred from arguments
auto v1 = mkVector(lvalue); // argument is a lvalue
auto v2 = mkVector(string{}); // argument is a rvalue
// type is explicilty stated
auto v3 = mkVector(lvalue); // argument is a lvalue
auto v4 = mkVector(""); // argument is a rvalue
В случае v3 не удается скомпилировать, поскольку U явно объявлено как U=string, поэтому U&& означает строку&&, а lvalue — это несовместимо.
Есть ли способ написать функцию mkVector, чтобы она корректно работала во всех возможных случаях, поддерживая идеальную пересылку?
Лучшее, что я мог придумать, это написать две перегрузки функции, но это не идеально, и если есть N аргументов вместо 1, потребуется 2^N возможных перегрузок.
template
auto mkVector(U&& x0)
{
return std::vector{std::move(x0)};
}
template
auto mkVector(const U& x0)
{
return std::vector{x0};
}
Подробнее здесь: https://stackoverflow.com/questions/784 ... y-declared