Рассмотрим этот фрагмент кода, который использует общую идиому создания шаблона функции, создающего экземпляр шаблона класса, специализированного по выведенному типу, как показано в 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разумны?