我有这个例子来生成一个向量中的唯一对象:
#include <iostream>
#include <vector>
#include <algorithm>
int v=0;
struct A
{
A() : refValue( v++)
{ std::cout<<"constructor refValue="<<refValue<<std::endl; }
A( const A &r ) : refValue(r.refValue)
{ std::cout<<"copy constructor refValue="<<refValue<<std::endl; }
A& operator=( const A &r )
{
refValue = r.refValue;
std::cout<<"operator= refValue="<<refValue<<std::endl;
return *this;
}
~A() { std::cout<<"destructor refValue="<<refValue<<std::endl; }
int refValue;
};
A GenerateUnique()
{
A unique;
return unique;
}
struct B
{
B( const int n) : v()
{
std::generate_n( std::back_inserter( v ), n, &GenerateUnique );
}
std::vector< A > v;
};
int main()
{
B b(3);
}
如果我将主要内容改为:
struct B
{
B( const int n) : v(n)
{
}
std::vector< A > v;
};
然后将一个A类型的对象复制到所有向量元素中。
有没有办法用所有唯一对象创建一个向量(如第一个例子中所示)?
为了更清楚:我有一个包含向量的类。此向量必须包含所有唯一对象(不是一个对象的副本)。我想在初始化列表中初始化它(而不是在构造函数的主体中)。
答案 0 :(得分:3)
它被复制,因为该构造函数的签名如下:
explicit vector( size_type count,
const T& value = T(),
const Allocator& alloc = Allocator());
很明显,您只需将默认构造的对象传递给此构造函数,然后将其复制。
如果要在初始化列表中初始化,显然只限于某些对象的构造函数。我想,你不想创建一个包装类来初始化初始化列表中的向量,所以我们仅限于向量的构造函数。唯一合理的是
template <class InputIterator>
vector( InputIterator first, InputIterator last,
const Allocator& alloc = Allocator() );
因此,您可以创建一个迭代器来返回所需数量的默认构造对象。
我建议只在构造函数体中构建。
答案 1 :(得分:3)
你的第一次尝试是有效的。
在当前的标准C ++ 03中这一行
std::vector< A > as( n );
明确定义为创建一个A
对象并复制n
次。
我相信在C ++ 0x中,这被更改为创建n
默认构造的A
s(一个小差异)。然后你或许可以在A
构造函数中做一些事情来使每个实例都是唯一的。
现在你不能。
答案 2 :(得分:1)
如前所述,您可以使用boost中的make_function_input_iterator
,如下所示:
#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/iterator/function_input_iterator.hpp>
// A && GenerateUnique the same ...
struct B
{
B( const int n) : v(boost::make_function_input_iterator(&GenerateUnique, 1), boost::make_function_input_iterator(&GenerateUnique, n))
{
}
std::vector< A > v;
};
int main()
{
B b(3);
}
但请注意,当我测试代码时,我看到了比第一个解决方案更多的复制构建/运算符=继续。接下来,还创建了一个附加对象(refvalue 3)(用于最后一个“stop”迭代器)。我不知道这个额外的行为是否可行,但如果您真的需要它,它可以在初始化列表中初始化向量。