带有C ++ 0x的“Double”函数

时间:2011-08-24 01:37:06

标签: c++ optimization c++11

假设我有以下简单的Vector类:

template <class N>
class Vector<N>
{
public:
  std::array<int, N> a;
};

我在double的第一次尝试如下:

template <class N>
Vector<N>&& double1(Vector<N>&& x) 
{ 
  for (int i = 0; i != N, ++i) { x.a[i] *= 2; }
  return static_cast<Vector<N>&&>(x);
}

这最初看起来不错,但如果我这样做:

auto x&& = double1(makeVector(1,2,3))

我会提到临时问题。

我的第二次尝试如下:

template <class N>
Vector<N> double2(Vector<N>&& x) 
{ 
  for (int i = 0; i != N, ++i) { x.a[i] *= 2; }
  return x;
}

这似乎没有对临时问题的上述引用,但我认为这是一个不必要的移动/复制返回。

我可以通过执行以下操作来避免引用临时问题和额外移动/复制:

template <class N>
void double3(Vector<N>& x) 
{ 
  for (int i = 0; i != N, ++i) { x.a[i] *= 2; }
}

但是我必须对这个论点进行修改,我觉得这有点凌乱。我还要指出临时工。

我的最终想法如下:

template <class N>
Vector<N> double4(Vector<N> x) 
{ 
  for (int i = 0; i != N, ++i) { x.a[i] *= 2; }
  return x;
}

如果参数存储在与结果相同的位置,那么会避免所有副本,但我不知道如何执行此操作。

基本上我正在寻找具有以下属性的双重功能:

(1)在分配auto时没有引用临时问题 (2)临时通过时不得复印件 (3)传递非临时参数时不修改参数。

任何人都知道如何把这三件事放在一起?

修改

或许更简单地说,这就是我想要的行为。

(1)如果参数是临时的,请将其修改到位 (2)否则,复印一份。

2 个答案:

答案 0 :(得分:2)

你的最终想法是正确有效的,请继续使用:

template <class N>
Vector<N> double4(Vector<N> x) 
{ 
  for (int i = 0; i != N, ++i) { x[i] *= 2; }
  return x;
}

答案 1 :(得分:1)

此代码没有意义。

首先,std :: array采用两个模板参数:类型和大小。其次,std :: array是一个聚合;它真的不可动。可以移动内容,但不能移动对象本身。

第三,你滥用r值引用没有明显的收益。如果你想要加倍,只需使用常规引用,就像在C ++ 0x之前一样。

  

但是我必须对这个论点进行修改,我觉得这有点凌乱。我还要指出临时工。

实际存储对象没有任何问题。并非一切都需要是暂时的。如果除了C ++不允许的其他原因之外,通过尝试暂时通过函数调用来获得绝对没有效率。

关于更改参数并没有什么“混乱”; C ++不是一种函数式语言。

哦,r值引用不是“临时引用”。他们可以引用临时工,但这不是他们唯一做的事情。