Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.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++ std::transform中的二进制运算符,向量为唯一_ptr_C++_C++11 - Fatal编程技术网

C++ std::transform中的二进制运算符,向量为唯一_ptr

C++ std::transform中的二进制运算符,向量为唯一_ptr,c++,c++11,C++,C++11,当我将标准库转换应用于唯一的_ptr向量时,我会感到困惑。我定义了一个二进制函子addScalar,它对unique_ptr进行2次常量引用,并返回对unique_ptr的常量引用,以避免复制(unique_ptr禁止复制) 然后我尝试在std::transform中使用它,但似乎unique_ptr根本不可能进行二进制操作,尽管我采取了所有预防措施来避免unique_ptr复制 有人知道如何将std::transform与std::unique\u ptr一起使用吗?还是我必须用for循环遍历

当我将标准库转换应用于唯一的_ptr向量时,我会感到困惑。我定义了一个二进制函子addScalar,它对unique_ptr进行2次常量引用,并返回对unique_ptr的常量引用,以避免复制(unique_ptr禁止复制)

然后我尝试在std::transform中使用它,但似乎unique_ptr根本不可能进行二进制操作,尽管我采取了所有预防措施来避免unique_ptr复制

有人知道如何将std::transform与std::unique\u ptr一起使用吗?还是我必须用for循环遍历向量并“手动”执行加法?我还想知道是否可以在我的functor中使用
unique\u ptr

这是我的班级:

#include "space.h"
#include "scalar.h"
#include <vector>
#include <algorithm>
#include <memory>

using std::vector;
using std::ostream;
using std::unique_ptr;

class addScalar
{
   public:
      unique_ptr<Scalar> const& operator()(unique_ptr<Scalar> const& scal1, unique_ptr<Scalar> const& scal2)
      {
         *scal1 += *scal2;
         return scal1;
      };
};

class Tensor4D
{
   public:
      Tensor4D(Space& space_in, int ncomp);
      Tensor4D(const Tensor4D& tens);
      Tensor4D& operator=(const Tensor4D& tens);
      size_t size() const {return comp.size();};
      ~Tensor4D();
   protected:
      Space* const space;
      vector<unique_ptr<Scalar>> comp;
   public:
      Tensor4D& operator+=(const Tensor4D& tens);
};
我发现以下编译器错误:

/usr/include/c++/4.8/bits/stl_algo.h: In instantiation of ‘_OIter std::transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation) [with _IIter1 = __gnu_cxx::__normal_iterator<const std::unique_ptr<Scalar>*, std::vector<std::unique_ptr<Scalar> > >; _IIter2 = __gnu_cxx::__normal_iterator<std::unique_ptr<Scalar>*, std::vector<std::unique_ptr<Scalar> > >; _OIter = __gnu_cxx::__normal_iterator<const std::unique_ptr<Scalar>*, std::vector<std::unique_ptr<Scalar> > >; _BinaryOperation = addScalar]’:
tensor4D.C:44:94:   required from here
/usr/include/c++/4.8/bits/stl_algo.h:4965:12: error: no match for ‘operator=’ (operand types are ‘const std::unique_ptr<Scalar>’ and ‘const std::unique_ptr<Scalar>’)
  *__result = __binary_op(*__first1, *__first2);
        ^
/usr/include/c++/4.8/bits/stl_algo.h:4965:12: note: candidates are:
In file included from /usr/include/c++/4.8/memory:81:0,
             from /home/gmartinon/Kadath/C++/Include/scalar.h:27,
             from tensor4D.h:5,
             from tensor4D.C:1:
/usr/include/c++/4.8/bits/unique_ptr.h:190:7: note: std::unique_ptr<_Tp, _Dp>& std::unique_ptr<_Tp, _Dp>::operator=(std::unique_ptr<_Tp, _Dp>&&) [with _Tp = Scalar; _Dp = std::default_delete<Scalar>]
   operator=(unique_ptr&& __u) noexcept
   ^
/usr/include/c++/4.8/bits/unique_ptr.h:190:7: note:   no known conversion for argument 1 from ‘const std::unique_ptr<Scalar>’ to ‘std::unique_ptr<Scalar>&&’
/usr/include/c++/4.8/bits/unique_ptr.h:203:2: note: template<class _Up, class _Ep> typename std::enable_if<std::__and_<std::is_convertible<typename std::unique_ptr<_Up, _Ep>::pointer, typename std::unique_ptr<_Tp, _Dp>::_Pointer::type>, std::__not_<std::is_array<_Up> > >::value, std::unique_ptr<_Tp, _Dp>&>::type std::unique_ptr<_Tp, _Dp>::operator=(std::unique_ptr<_Up, _Ep>&&) [with _Up = _Up; _Ep = _Ep; _Tp = Scalar; _Dp = std::default_delete<Scalar>]
  operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
  ^
/usr/include/c++/4.8/bits/unique_ptr.h:203:2: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/4.8/algorithm:62:0,
             from tensor4D.h:8,
             from tensor4D.C:1:
/usr/include/c++/4.8/bits/stl_algo.h:4965:12: note:   types ‘std::unique_ptr<_Tp, _Dp>’ and ‘const std::unique_ptr<Scalar>’ have incompatible cv-qualifiers
  *__result = __binary_op(*__first1, *__first2);
        ^
In file included from /usr/include/c++/4.8/memory:81:0,
             from /home/gmartinon/Kadath/C++/Include/scalar.h:27,
             from tensor4D.h:5,
             from tensor4D.C:1:
/usr/include/c++/4.8/bits/unique_ptr.h:211:7: note: std::unique_ptr<_Tp, _Dp>& std::unique_ptr<_Tp, _Dp>::operator=(std::nullptr_t) [with _Tp = Scalar; _Dp = std::default_delete<Scalar>; std::nullptr_t = std::nullptr_t]
       operator=(nullptr_t) noexcept
       ^
/usr/include/c++/4.8/bits/unique_ptr.h:211:7: note:   no known conversion for argument 1 from ‘const std::unique_ptr<Scalar>’ to ‘std::nullptr_t’
/usr/include/c++/4.8/bits/unique_ptr.h:274:19: note: std::unique_ptr<_Tp, _Dp>& std::unique_ptr<_Tp, _Dp>::operator=(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Scalar; _Dp = std::default_delete<Scalar>] <near match>
   unique_ptr& operator=(const unique_ptr&) = delete;
               ^
/usr/include/c++/4.8/bits/unique_ptr.h:274:19: note:   no known conversion for implicit ‘this’ parameter from ‘const std::unique_ptr<Scalar>*’ to ‘std::unique_ptr<Scalar>*’
/usr/include/c++/4.8/bits/stl_algo.h:在“_iiterstd::transform”(_IIter1,_IIter1,_IIter2,_iiter,_iiter,_iiter,_iiter,_iiter,_bitaryoperation)[带_IIter1=u gnu cxx::u正常迭代器;_IIter2=_gnucxx:u gnu正常迭代器;u cxx:u gnu=标准标量迭代器]:
tensor4D.C:44:94:此处需要
/usr/include/c++/4.8/bits/stl_-algo.h:4965:12:错误:与“operator=”不匹配(操作数类型为“const std::unique_ptr”和“const std::unique_ptr”)
*__结果=uuu二进制运算(*uuu first1,*uuu first2);
^
/usr/include/c++/4.8/bits/stl_algo.h:4965:12:注:候选项包括:
在/usr/include/c++/4.8/memory:81:0中包含的文件中,
from/home/gmartinon/Kadath/C++/Include/scalar.h:27,
从张量4d.h:5开始,
从tensor4D.C:1:
/usr/include/c++/4.8/bits/unique\u ptr.h:190:7:注:std::unique\u ptr&std::unique\u ptr::operator=(std::unique\u ptr&)[带标量;\u Dp=std::default\u delete]
运算符=(唯一\u ptr&&\u_)无例外
^
/usr/include/c++/4.8/bits/unique\u ptr.h:190:7:注意:参数1从“const std::unique\u ptr”到“std::unique\u ptr&”的转换未知
/usr/include/c++/4.8/bits/unique\u ptr.h:203:2:注意:模板typename std::enable\if::type std::unique\u ptr::operator=(std::unique\u ptr&)[with-Up=\u Up;\u Ep=\u Tp=Scalar;\u Dp=std::default\u delete]
运算符=(唯一\u ptr&&\u_)无例外
^
/usr/include/c++/4.8/bits/unique\u ptr.h:203:2:注意:模板参数推导/替换失败:
在/usr/include/c++/4.8/algorithm:62:0中包含的文件中,
从张量4d.h:8开始,
从tensor4D.C:1:
/usr/include/c++/4.8/bits/stl_-algo.h:4965:12:注意:类型“std::unique_-ptr”和“const-std::unique_-ptr”具有不兼容的cv限定符
*__结果=uuu二进制运算(*uuu first1,*uuu first2);
^
在/usr/include/c++/4.8/memory:81:0中包含的文件中,
from/home/gmartinon/Kadath/C++/Include/scalar.h:27,
从张量4d.h:5开始,
从tensor4D.C:1:
/usr/include/c++/4.8/bits/unique\u ptr.h:211:7:注:std::unique\u ptr&std::unique\u ptr::operator=(std::nullptr\t)[带标量;\u Dp=std::default\u delete;std::nullptr\u t=std::nullptr\t]
运算符=(nullptr_t)noexcept
^
/usr/include/c++/4.8/bits/unique\u ptr.h:211:7:注意:参数1从“const std::unique\u ptr”到“std::nullptr\t”的转换未知
/usr/include/c++/4.8/bits/unique\u ptr.h:274:19:注:std::unique\u ptr&std::unique\u ptr::operator=(const std::unique\u ptr&)[带标量;\u Dp=std::default\u delete]
唯一\u ptr&运算符=(常量唯一\u ptr&)=删除;
^
/usr/include/c++/4.8/bits/unique_ptr.h:274:19:注意:隐式“this”参数从“const std::unique_ptr*”到“std::unique_ptr*”没有已知的转换

<代码> > < >代码> STD:C++:转换< <代码> >:< /P> binary_op不能使任何迭代器无效,包括end 迭代器,或修改所涉及范围的任何元素


对于您来说,最好的方法是根据特定需要实现您自己的转换函数。

addScalar的返回类型将分配给
unique\u ptr
,因此它无法返回常量引用,因为
unique\u ptr
没有副本分配。因此,您必须按值返回以调用移动分配

要避免构造新的
标量
,可以使用移动到
addScalar
,然后移动赋值以覆盖移动自值:

class addScalar 
{
public:
    unique_ptr<Scalar> operator()(unique_ptr<Scalar> scal1,
                                  unique_ptr<Scalar> const& scal2) {
      *scal1 += *scal2;
      return scal1;
    };
};

Tensor4D& Tensor4D::operator+=(const Tensor4D& tens)
{
   assert(comp.size() == tens.comp.size());
   transform(make_move_iterator(comp.begin()), make_move_iterator(comp.end()),
               tens.comp.begin(), comp.begin(), addScalar());
   return *this;
}
类addScalar { 公众: 唯一\u ptr运算符()(唯一\u ptr scal1, 唯一性(ptr常量和刻度2){ *scal1+=*scal2; 返回量表1; }; }; Tensor4D和Tensor4D::运算符+=(常量Tensor4D和tens) { 断言(comp.size()==tens.comp.size()); 变换(make_move_iterator(comp.begin()),make_move_iterator(comp.end()), tens.comp.begin(),comp.begin(),addScalar()); 归还*这个; }
Andrey提出了一个问题,目前还不清楚根据标准是否严格允许这样做。我会把这个交给语言律师。另见


您无法复制唯一指针,因此不允许使用
std::transform
尝试的复制赋值。那么
shared\u ptr
会执行此任务吗?可能会,但我觉得这不适合您的问题。你不是真的想分享所有权。从一个手动循环开始,然后看看是否有任何一个可以被算法化。非常感谢,现在它工作得很好!我不知道这些移动迭代器,太有用了!
class addScalar 
{
public:
    unique_ptr<Scalar> operator()(unique_ptr<Scalar> scal1,
                                  unique_ptr<Scalar> const& scal2) {
      *scal1 += *scal2;
      return scal1;
    };
};

Tensor4D& Tensor4D::operator+=(const Tensor4D& tens)
{
   assert(comp.size() == tens.comp.size());
   transform(make_move_iterator(comp.begin()), make_move_iterator(comp.end()),
               tens.comp.begin(), comp.begin(), addScalar());
   return *this;
}