构造时,用整数序列填充向量
Populate vector with integer sequence, on construction
我正试图在向量的构造上用整数序列填充vector
(或其他容器)(与此问题相反)。以下代码实现了我的意图,使用vector
的range构造函数和Boost的counting_range:
#include <iostream>
#include <vector>
#include <boost/range/counting_range.hpp>
using namespace std;
int main () {
vector<int> test_vector(boost::counting_range(2,10).begin(),boost::counting_range(2,10).end());
for (auto i : test_vector) cout << i << endl;
}
问题:
- 我可以消除
counting_range(2,10).begin()
和counting_range(2,10).end()
中的重复吗?目前,我正在两次指定(2,10)的范围。 - 这可以在没有Boost的情况下完成吗?只使用普通的C++11或C++0x编辑:还是C++14
编辑:
- 我想实例化向量并在一条语句中指定范围。例如,在Python中,我可以编写
test_vector=range(2,9)
。在R/Octave/Matlab中可以编写test_vector=2:9
或test_vector=seq(2,9,1)
。在这方面,我对以上内容感到满意。 - 我在上面使用了"2"answers"10",但范围的边界可以是动态的,任何整数a,b在a的范围内;b。因此,像{2,3,…,9}这样的初始化列表是不可取的,因为它必须在编译时指定。
我上面使用的方法也可以用于在一条语句中初始化其他容器;以下方法也适用:
unordered_set test_set(boost::counting_range(2,10).begin(),boost::counting_range(2,10).end());
如果任何解决方案也是"独立于容器"的,那就太好了。
- 我同意@davidrodriguez-dribeas的观点,即我们可以通过初始化构造函数体中的向量来坚持Meyer的项;它没有必要在构造函数的初始化列表中完成。因此,我删除了下面的这一部分
动机
:我想这么做是因为我想遵守我代码中其他地方的有效C++中Meyer的第4项("确保对象在使用之前已经初始化。")。例如:
class my_class {
public:
my_class()
:vec(boost::counting_range(2,10).begin(),boost::counting_range(2,10).end()) {}
vector<int> vec;
};
不要过度。简单的做法是默认初始化向量,保留并从范围初始化。
确保在使用对象之前对其进行初始化
这并不意味着必须在初始化列表中完全初始化成员,而不是在构造函数完成时必须完全初始化my_class
对象。
除此之外,为了方便起见,在香草C++中可以做一些不同的事情来处理这一问题,比如创建一个辅助函数并按值返回向量:
std::vector<int> create_vector() {
std::vector<int> v;
// ...
return v;
}
但我不会使用这个(或任何其他替代方案)来初始化成员,只有当需要时(向量是const
可能是充分的借口:)
您可以使用由范围分隔的序列来构造std::vector<T>
。您只需要一个合适的输入迭代器来初始化序列,然后就可以定义迭代器,这样您就可以为end
使用默认构造的迭代器了,例如:
class counter: public std::iterator<std::input_iterator_tag, int> {
int current;
int end;
public:
counter(): current(), end() {}
counter(int c, int e): current(c), end(e) {}
int const& operator*() const { return this->current; }
counter& operator++() { ++current; return *this; }
counter operator++(int) { counter rc(*this); ++current; return rc; }
bool operator== (counter const& other) const {
return (end - current) == (other.end - other.current);
}
bool operator!= (counter const& other) const { return !(*this == other); }
};
std::vector<int> v(counter(2, 10), counter());
Boost方法是使用boost::copy_range
:
auto vec = boost::copy_range<std::vector<int>>(boost::irange(0, 10));
boost::copy_range
是一个函数模板,它返回其第一个模板参数类型的对象:
template< typename SeqT, typename Range >
inline SeqT copy_range( const Range& r )
{
return SeqT( boost::begin( r ), boost::end( r ) );
}
您必须将返回类型指定为模板参数,这可能违反DRY,但可以避免使用AAA样式,如我上面的示例所示,或者在类初始值设定项中使用decltype:
class S {
public:
S() : vec(boost::copy_range<decltype(vec)>(boost::irange(0, 10)) {}
private:
const std::vector<int> vec;
};
这让从未让任何人失望过,而且它完全是普通的,甚至可以与C++03一起使用(如果你像我一样后台端口begin
、end
;如果不是,只使用编译时数组大小):
int inits[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10};
vector<int> test_vector ( begin(inits), end(inits) );
如果序列是另一种序列,您只需要调整初始化数组,或者使用生成器对象,然后bam!它完成了。
至于避免(1)中的重复,如果以下内容有任何问题,会有什么问题?
const boost::counting_range init_range(2,10);
vector<int> test_vector( begin(init_range), end(init_range) );
您可以直接使用boost::counting_迭代器来初始化您的序列,而不是创建boost::counting_range。
#include <iostream>
#include <vector>
#include <boost/iterator/counting_iterator.hpp>
int main ()
{
std::vector<int> aVec(boost::counting_iterator<int>(0), boost::counting_iterator<int>(10));
for (int i : aVec)
{
std::cout << i << std::endl;
}
return 0;
}
- 用C++中的数字和条件填充向量
- 是否有可能让 c++ dll 在后台运行 python 程序并让它填充向量图?如果是这样,如何?
- 有没有办法使用数组填充向量?
- 用对对填充向量未按预期工作
- 可选类输入中的 C++ 填充向量
- 用构造函数调用填充向量
- 错误:以增量方式填充向量时,表达式必须具有整数或无作用域枚举类型
- C 中的填充向量
- 从输入文件中填充向量的向量
- 在循环中创建和填充向量
- 如何使用两列C 从文本文件中填充向量
- 在C++编程语言中,如何用n个向量长度的所有可能的字符串组合来填充向量
- 使用精神,如何在AST结构内填充向量
- 如何用键盘输入来填充C++向量
- 用随机数C 填充向量
- 构造时,用整数序列填充向量
- 使用指向部分专用函数成员的指针自动填充向量
- 用于填充向量的c++有状态函子
- C++:在类构造函数中填充向量后,向量成员被销毁
- 如何在类中用不同类的对象填充向量