gpt4 book ai didi

c++ - 这是通用引用吗? std::forward 在这里有意义吗?

转载 作者:IT老高 更新时间:2023-10-28 22:58:53 24 4
gpt4 key购买 nike

考虑一下这段代码,它使用了一个常见的习惯用法,即让函数模板构造一个专门针对推导类型的类模板的实例,如 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调用的情况下,在我看来,考虑构造函数的参数可能是有意义的foo 是通用引用,因为 T 已由函数模板 make_foo。相同的引用折叠规则将适用这样 v 的类型在两个函数中是相同的。在这种情况下,TU可以说是推导出来的。

所以我的问题是双重的:

  • foo 的构造函数的参数视为在推断出 T 的有限情况下的通用引用在调用者的通用引用上下文中,如我的示例所示?
  • 在我的示例中,std::forward 的两种用法都合理吗?

最佳答案

make_foo与“正确”在同一个球场,但 foo不是。 foo构造函数当前接受非推导的 T && ,并且转发可能不是您的意思(但请参阅@nosid 的评论)。总而言之,foo应该带一个类型参数,有一个模板化的构造函数,并且 maker 函数应该做衰减:

template <typename T>
struct foo
{
T v_;

template <typename U>
foo(U && u) : v_(std::forward<U>(u)) { }
};

template <typename U>
foo<typename std::decay<U>::type> make_foo(U && u)
{
return foo<typename std::decay<U>::type>(std::forward<U>(u));
}

在 C++14 中,maker 函数的编写变得更简单了:

template <typename U>
auto make_foo(U && u)
{ return foo<std::decay_t<U>>(std::forward<U>(u)); }

正如您现在编写的代码,int a; make_foo(a);将创建 foo<int &> 类型的对象.这将在内部存储 int , 但它的构造函数只接受 int &争论。相比之下,make_foo(std::move(a))将创建一个 foo<int> .

所以按照你写的方式,类模板参数决定了构造函数的签名。 (std::forward<T>(v) 以一种变态的方式仍然有意义(感谢@nodis 指出这一点),但这绝对不是“转发”。)

这很不寻常。通常,类模板应确定相关的包装类型,构造函数应接受任何可用于创建包装类型的内容,即构造函数应该是函数模板。

关于c++ - 这是通用引用吗? std::forward 在这里有意义吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24497311/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com