考虑一下这段代码,它使用了一个常见的习惯用法,即让函数模板构造一个专门针对推导类型的类模板的实例,如std::make_uniqueand所示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合理吗?