c++ - 使用 n_copy 将前 n 个元素从一个向量复制到另一个向量的模板函数导致编译错误
问题描述
我正在使用以下模板函数将前 n 个元素从一个向量复制到另一个向量。
// Example program
#include <iostream>
#include <string>
#include <vector>
template <typename Range>
inline std::vector<typename Range::value_type> take(const Range &iRange, int nbrElements) {
std::vector<typename Range::value_type> result;
if (nbrElements > iRange.size()) {
nbrElements = iRange.size();
}
std::copy_n(iRange, nbrElements, std::back_inserter(result));
return result;
}
int main()
{
std::vector<int> source = { 1, 2, 3, 4, 5, 6, 7,};
std::vector<int> destination = take(source, 7);
return 0;
}
问题是我收到以下错误,我不明白为什么:
In instantiation of 'std::vector<typename Range::value_type>
take(const Range&, int) [with Range = std::vector<int>; typename
Range::value_type = int]':
22:48: required from here
10:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
In file included from /usr/include/c++/4.9/algorithm:62:0,
from 5:
/usr/include/c++/4.9/bits/stl_algo.h: In instantiation of '_OIter std::copy_n(_IIter, _Size, _OIter) [with _IIter = std::vector<int>;
_Size = int; _OIter = std::back_insert_iterator<std::vector<int> >]':
14:62: required from 'std::vector<typename Range::value_type> take(const Range&, int) [with Range = std::vector<int>; typename
Range::value_type = int]'
22:48: required from here
/usr/include/c++/4.9/bits/stl_algo.h:804:39: error: no matching function for call to '__iterator_category(std::vector<int>&)'
std::__iterator_category(__first));
^
/usr/include/c++/4.9/bits/stl_algo.h:804:39: note: candidate is:
In file included from /usr/include/c++/4.9/bits/stl_algobase.h:65:0,
from /usr/include/c++/4.9/bits/char_traits.h:39,
from /usr/include/c++/4.9/ios:40,
from /usr/include/c++/4.9/ostream:38,
from /usr/include/c++/4.9/iostream:39,
from 2:
/usr/include/c++/4.9/bits/stl_iterator_base_types.h:201:5: note: template<class _Iter> typename
std::iterator_traits<_Iterator>::iterator_category
std::__iterator_category(const _Iter&)
__iterator_category(const _Iter&)
^
/usr/include/c++/4.9/bits/stl_iterator_base_types.h:201:5: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/stl_iterator_base_types.h: In substitution of 'template<class _Iter> typename
std::iterator_traits<_Iterator>::iterator_category
std::__iterator_category(const _Iter&) [with _Iter =
std::vector<int>]':
/usr/include/c++/4.9/bits/stl_algo.h:804:39: required from '_OIter std::copy_n(_IIter, _Size, _OIter) [with _IIter =
std::vector<int>; _Size = int; _OIter =
std::back_insert_iterator<std::vector<int> >]'
14:62: required from 'std::vector<typename Range::value_type> take(const Range&, int) [with Range = std::vector<int>; typename
Range::value_type = int]'
22:48: required from here
/usr/include/c++/4.9/bits/stl_iterator_base_types.h:201:5: error: no type named 'iterator_category' in 'struct
std::iterator_traits<std::vector<int> >'
解决方案
代码有两个问题。第一个是它需要有#include <algorithm>
,它定义了std::copy_n
,第二个是你需要取begin()
of 范围。
修复后,代码如下所示:
// Example program
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
template <typename Range>
inline std::vector<typename Range::value_type> take(const Range &iRange, int nbrElements) {
std::vector<typename Range::value_type> result;
if (nbrElements > iRange.size()) {
nbrElements = iRange.size();
}
std::copy_n(iRange.begin(), nbrElements, std::back_inserter(result));
return result;
}
int main()
{
std::vector<int> source = { 1, 2, 3, 4, 5, 6, 7,};
std::vector<int> destination = take(source, 7);
return 0;
}
较短的版本
我们可以利用std::vector
's range 构造函数来编写一个更短、更高效的take
' std::vector
s range 构造函数:
template <class Range, class value_t = typename Range::value_type>
std::vector<value_t> take(const Range &range, size_t count) {
// Ensure count is at most range.size()
count = std::min(count, range.size());
return std::vector<value_t>(range.begin(), range.begin() + count);
}
推荐阅读
- android - 无法在 ViewModel 中调用协程作用域函数
- javascript - material-ui 组件样式自定义 - 将选择组件的颜色更改为白色
- python - 为什么我使用 smtp.sendmail(toAddress, fromAddress, message) 时没有显示该消息?
- sql-server - 我想使用时间列选择最近 7 天的数据
- python - pd.cut cannot used for range in negative value
- python - Webscraping Python 试图拉变化的“id”
- git - 用于将自动工具构建的 git 子模块添加到 cmake 项目的 Cmake 宏
- vue.js - 你可以在 Vuejs 中将参数传递给 mixin 吗?
- database - 服务器与数据库的通信
- unity3d - 如何重置 IEnumerator 变量?