Рассмотрим этот фрагмент кода, который использует общую идиому создания шаблона функции, создающего экземпляр шаблона класса, специализированного по выведенному типу, как показано в std::make_unique
и std::make_tuple
, например:
template <typename T>
struct foo
{
std::decay_t<T> v_;
foo(T&& v) : v_(std::forward<T>(v)) {}
};
template <typename U>
foo<U> make_foo(U&& v)
{
return { std::forward<U>(v) };
}
В контексте "универсальных ссылок" Скотта Мейерса аргумент
make_foo
является универсальной ссылкой, поскольку ее тип U&&
, где U
равен
выводится. Аргумент конструктору foo
не является универсальной ссылкой
потому что хотя его тип T&&
, T
(вообще говоря) не выведен.
Но в случае, когда конструктор foo
вызывается make_foo
, он
мне кажется, что имеет смысл думать об аргументе конструктору
of foo
как универсальная ссылка, потому что T
был выведен
шаблон функции make_foo
. Будут применяться те же правила обрушения ссылок
так что тип v
в обеих функциях одинаковый. В этом случае оба T
и U
можно сказать, что оно было выведено.
Итак, мой вопрос двоякий:
- Имеет ли смысл думать о аргументе конструктору
foo
как о универсальная ссылка в ограниченных случаях, в которойT
было выведено в универсальном справочном контексте вызывающим, как в моем примере? - В моем примере оба использования
std::forward
разумны?