gpt4 book ai didi

c++ - 当我知道传入的类型时,完美转发的最佳方式是什么

转载 作者:太空宇宙 更新时间:2023-11-04 16:20:33 27 4
gpt4 key购买 nike

如果我理解正确的话,完美转发使用通用引用来推断传递的参数是左值还是右值。这很好。

也就是说,要实现这个功能,我必须制作模板函数。一个可能的例子是

template <class T>
void func(T&& str){
auto s = std::forward<T>(str);
cout << s << endl;
}

但是,如果我知道 T 怎么办?的 func应该是 std::string仅有的?我认为一种可能的选择是使用 std::enable_ifstd::is_same限制类型 T .但它变得越来越冗长。

这种情况的最佳做法是什么?

编辑:

根据 Kerrek SB 的建议,我正在尝试制作一个可能的场景。

我正在制作一个包含 std::vector<double> 的类(class)作为成员(member)。然后,我想制作一个也采用 std::vector<double> 的构造函数.如果参数是左值,我想将它复制到一个成员,但如果不是,我想移动它。

这是某种可能的例子吗?

最佳答案

如果您不想要模板,您有两个选择:

  1. 按值传递并移动;
  2. 有一个拷贝重载和一个移动重载;

第一个选项将让编译器根据需要决定是移动还是复制到您的参数中。然后你的代码不再关心它是来自左值还是右值(如果它来自左值它已经是一个拷贝)并将其移动到成员中。撇开优化不谈,这可能会产生一次移动的开销,但如果移动成本较低(如 std::vector 的情况),则可以忽略不计。

foo(std::vector<double> v) : v(std::move(v)) {}

对于第二个选项,您的代码而不是编译器做出决定。这避免了前面提到的一次移动可能产生的开销,但它存在不可扩展的问题:如果你想复制或移动四个这样的参数,你将需要十六个不同的重载(这正是完美转发试图解决的问题).

foo(std::vector<double> const& v) : v(v) {}
foo(std::vector<double>&& v) : v(std::move(v)) {}

模板选项将适当缩放,但可能需要一些约束以防止在不希望的情况下使用它(在不受约束的模板构造函数的情况下,它可以是 mistakenly used for copies )。

当然,如果您使用移动退化为拷贝的类型(如 std::array),您可以只使用该集合的第一个重载。

关于c++ - 当我知道传入的类型时,完美转发的最佳方式是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17209650/

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