考虑一下这段代码,它使用了一个常见的习惯用法,即让函数模板构造一个专门针对推导类型的类模板的实例,如std::make_unique
and所示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) };
}
在 Scott Meyers 的“通用引用”的上下文中,参数 to
make_foo
是通用引用,因为它的类型是推导的U&&
位置。U
构造函数的参数foo
不是通用引用,因为尽管它的类型是T&&
,但T
(通常)不是推导的。
但是在构造函数的情况下,在foo
我make_foo
看来,将构造函数的参数foo
视为通用引用可能是有意义的,因为T
已经由函数模板推导出来make_foo
。将应用相同的引用折叠规则,以便v
两个函数中的类型相同。在这种情况下,两者T
和U
都可以说已经推导出来了。
所以我的问题是双重的:
- 在调用者在通用引用上下文中推断出来
foo
的有限情况下,将构造函数的参数视为通用引用是否有意义,例如我的示例?T
- 在我的例子中,这两种用法都
std::forward
合理吗?