Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ &引用;“双”字;函数与C++;0x_C++_Optimization_C++11 - Fatal编程技术网

C++ &引用;“双”字;函数与C++;0x

C++ &引用;“双”字;函数与C++;0x,c++,optimization,c++11,C++,Optimization,C++11,假设我有以下简单的向量类: template <class N> class Vector<N> { public: std::array<int, N> a; }; 一开始看起来不错,但如果我这样做了: auto x&& = double1(makeVector(1,2,3)) 我会参考临时问题 我的第二次尝试如下: template <class N> Vector<N>&& double1(

假设我有以下简单的向量类:

template <class N>
class Vector<N>
{
public:
  std::array<int, N> a;
};
一开始看起来不错,但如果我这样做了:

auto x&& = double1(makeVector(1,2,3))
我会参考临时问题

我的第二次尝试如下:

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);
}
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;
}
模板
向量双2(向量和x)
{ 
对于(inti=0;i!=N,++i){x.a[i]*=2;}
返回x;
}
这似乎没有提到上述临时问题,但我认为这是一个不必要的移动/复制返回

我可以通过以下操作避免提及临时问题和额外的移动/复制:

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);
}
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;
}
模板
空双3(矢量和x)
{ 
对于(inti=0;i!=N,++i){x.a[i]*=2;}
}
但我必须对论点进行修改,我认为这有点混乱。我还要说出临时工的名字

我的最终想法如下:

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);
}
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;
}
模板
向量双4(向量x)
{ 
对于(inti=0;i!=N,++i){x.a[i]*=2;}
返回x;
}
如果参数存储在与结果相同的位置,则可以避免所有副本,但我不确定如何执行此操作

基本上,我正在寻找具有以下属性的双精度函数:

(1) 使用auto分配时,没有对临时问题的引用。
(2) 通过临时文件时没有副本。
(3) 在传递非临时参数时不修改参数

有人知道如何把这三件事放在一起吗

编辑

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

(1) 如果该参数是临时参数,请就地修改。

(2) 否则,请复制一份。

您的最终想法是正确和有效的,请继续:

template <class N>
Vector<N> double4(Vector<N> x) 
{ 
  for (int i = 0; i != N, ++i) { x[i] *= 2; }
  return x;
}
模板
向量双4(向量x)
{ 
对于(int i=0;i!=N,++i){x[i]*=2;}
返回x;
}

此代码没有意义

首先,std::array接受两个模板参数:类型和大小。第二,std::array是一个聚合;它实际上不是可移动的。可以移动内容,但不能移动对象本身

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

但我必须对论点进行修改,我认为这有点混乱。我还要说出临时工的名字

必须实际存储对象没有什么错。并非所有的事情都需要是暂时的。如果试图通过一个函数调用来临时调用一个函数,如果没有C++不允许的原因,则完全没有效率。 改变一个参数并没有什么“混乱”;C++不是一种函数语言。
哦,r值的引用并不是“临时引用”。他们可以引用临时引用,但这不是他们唯一做的事。

我怀疑这是可能的。您无法使其在通过临时复制后仍使用结果。也不能使其在传递非临时参数时不修改参数,也不能使其不复制。不要编写返回右值引用的函数。一个普通的老参考有什么不对?为什么在第一次尝试时,你实际上准备移动你的论证,然后将其重新分配给另一个变量,而改变论证却“混乱”了呢?还有,这有什么意义,您的类不包含任何类型的资源处理程序,这些资源处理程序甚至不会从移动语义中受益。@Darren:我们可能应该将其称为
ArrayList
,将其实现为boost.any的链接列表,并强制用户将内容强制转换回所需的类型。听起来很乱,你说呢?我有另一个项目的计划,我将称之为垃圾收集者,这将使它比你在C\C++中看到的任何容器都要好。@Clinton:你是否启用了优化并检查了所有这些副本是否都被制作出来了?我不会说这是有效的。或者正确,因为
std::array
有两个模板参数,而不是一个。所以
Vector
没有意义。而且你似乎做了很多不必要的复制,因为
std::array
s数据无法移动。@Nicol:不管有多少模板参数
std::array
都有-
Vector
的声明只有一个模板参数。就不必要的复制而言,如果不是针对
std::array
@Nicol,这个答案通常是正确的:将只调用一次复制构造函数(除非编译器太笨,无法在函数返回的位置构造
x
)。为什么会有这么多不必要的复制?@leftaroundabout:我记得,如果所讨论的对象是函数的参数,那么复制省略就无法工作。不过我并不完全确定。@leftaroundabout:如果向量是临时的,为什么需要任何副本。数据已经存在,只需要加倍。为什么要复制然后销毁它?