如何使用移动语义迭代器和模板

时间:2017-09-06 16:04:21

标签: c++ templates move-semantics

我想写函数来添加项目。 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
     */
}

是否可以为函数设置单个名称并区分输入迭代器?

1 个答案:

答案 0 :(得分:4)

由于您使用迭代器插入列表,因此最直接的解决方案是使用移动迭代器。使用移动迭代器,您无需更改模板函数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算法旨在与普通的非常量迭代器一起使用。移动项目功能的用法如下:

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())
);