【问题标题】:How to use move semantics iterators and templates如何使用移动语义迭代器和模板
【发布时间】:2018-02-15 05:10:03
【问题描述】:

我想编写函数来添加项目。 addItem 和 addItems 每个都有一个移动变量。后者接受两个输入迭代器。要添加单个项目,我可以使用右值引用重载签名。但是如何重载模板函数以使用移动语义?

void addItem(const shared_ptr<Item>& item, uint score) {
    // code that copies the shared_ptr…
}

void addItem(shared_ptr<Item>&& item, uint score) {
    // code that moves the shared_ptr…
}

template<typename Iterator>
void addItems(Iterator begin, Iterator end) {
    /*
     * What to do here to take both move and normal iterators?
     * Since I cannot overload by signature I dont know how to
     * differentiate between move and non move iterators
     */
}

是否可以为函数使用一个名称并区分输入迭代器?

【问题讨论】:

  • 你看过std::make_move_iterator吗?
  • 我有,但我不明白如何重载函数以同时接受移动和非移动迭代器。
  • @ManuelSchneid3r:您当前的签名接受 all 迭代器

标签: c++ templates move-semantics


【解决方案1】:

由于您使用迭代器来插入列表,因此最直接的解决方案是使用移动迭代器。使用移动迭代器,您无需更改模板函数addItems。移动迭代器会将引用的元素移动到新容器中:

// Same function as before
addItems(
    std::make_move_iterator(someList.begin()),
    std::make_move_iterator(someList.end())
);

或者,您可以提供一个移动插入函数,该函数使用std::move 算法:

template<typename Iterator>
void moveItems(Iterator begin, Iterator end) {
    std::move(begin, end, thelist.end());
}

此重载会将每个元素移动到thelist 容器。 std::move 算法旨在与普通的非 const 迭代器一起使用。移动项功能是这样使用的:

std::vector<int> vec{1, 2, 3};

// move each ints into the new container
moveItems(vec.begin(), vec.end());

// With your old function, move semantics
// can still be applied with move Iterators
addItems(
    std::make_move_iterator(vec.begin()),
    std::make_move_iterator(vec.end())
);

【讨论】:

  • 如果我不通过移动迭代器怎么办?我两个都需要。
  • @ManuelSchneid3r 两者都是什么?有没有办法改进这个答案?
  • 好吧,我可以通过在一个函数中传递一个引用并在另一个函数中传递一个右值引用来重载 addItem 函数。模板函数并非如此。所以我想了解如何像在 addItem 函数中一样为右值和左值引用重载这个 addItems 函数。如果我将常规迭代器(非移动)传递给您的 moveItems 函数会发生什么?
  • @ManuelSchneid3r 迭代器不通过引用传递。迭代器是按值传递的。没有超负荷的事情要做。如果您要将容器作为参数,我也会按值获取容器并移动包含的元素。
猜你喜欢
  • 1970-01-01
  • 2011-07-01
  • 2011-04-14
  • 1970-01-01
  • 1970-01-01
  • 2010-10-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多