为什么stl在算法中使用`const T&`而不是`T &&`

问题描述 投票:0回答:2

我正在编写类似的代码:

template<bool B, typename IfT, typename ThenT>
using conditional_t = std::conditional_t<B, IfT, ThenT>;

template <bool B,
  typename IfT, typename ThenT>
constexpr auto conditional_v(IfT&& t1, ThenT&& t2)
  -> conditional_t<B, IfT, ThenT> {
  if constexpr (B) {
    return t1;
  } else {
    return t2;
  }
}

如果通过conditional_v<true>(0, 1)之类的值传递,我们可以得到

template<>
inline constexpr conditional_t<true, int, int> conditional_v<true, int, int>(int && t1, int && t2)
{
  if constexpr(true) {
    return t1;
  }

}

如果通过引用,例如conditional_v<true>(i, j),我们将得到

template<>
inline constexpr conditional_t<true, int &, int &> conditional_v<true, int &, int &>(int & t1, int & t2)
{
  if constexpr(true) {
    return t1;
  }

}

[当我指的是stl时,例如max

template< class T >
constexpr const T& max( const T& a, const T& b );

它们大多由const T&而不是T&&传递。

所以我得到一个问题:在我的情况下是否应该使用const T&(就像conditional_t,conditional_v设计为在comipler时选择一个初始值一样。)

c++ reference stl
2个回答
0
投票

请考虑以下代码:

int foo = bar(); // some function that returns a value we don't know
int foo2 = std::max(foo, 100); // make sure it's no more than 100

如果std::max接受&&作为参数,您将如何编写该代码?


0
投票

T &&的引入是通过“窃取”传递的对象资源来避免不必要的复制。假设对象rhs具有指向某些已分配资源rhs.p的指针,则典型用法是

void steal (T&& rhs){
  p=rhs.p;
  rhs.p=nullptr;
} 

由于在您的情况下std::max不打算更改参数,因此没有理由通过右值引用传递参数。同样,您将无法将其与左值引用一起使用。除了命名变量之外,const T&还允许我们传递临时变量。例如

struct Test {};
Test returnObject(){
   Test t;
   return t;
}

int main(){
Test x;
Test& y=x;
Test&& z=x;//error cannot bind rvalue to lvalue
Test& r=returnObject();// error: cannot bind lvalue to rvalue
const Test& a=returnObject();// OK
Test&& b=returbObject();// OK
}
© www.soinside.com 2019 - 2024. All rights reserved.