如何生成具有唯一值的向量?
我有一个将唯一对象生成到向量中的示例:
#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);
}
如果我将 main 更改为:
struct B
{
B( const int n) : v(n)
{
}
std::vector< A > v;
};
那么类型 A 的一个对象将被复制到所有向量元素中。
有没有办法创建一个包含所有唯一对象的向量(如第一个示例)?
为了更清楚地说:我有一个包含向量的类。该向量必须包含所有唯一对象(而不是一个对象的副本)。我想在初始化列表中初始化它(而不是在构造函数的主体中)。
I have this example to generate unique objects into a vector :
#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);
}
If I change my main into this :
struct B
{
B( const int n) : v(n)
{
}
std::vector< A > v;
};
then one object of type A will be copied into all vector elements.
Is there a way to create a vector with all unique objects (like in the 1st example)?
To make it more clear : I have a class containing a vector. This vector must contain all unique objects (not a copy of one object). And I would like to initialize it in the initialization list (not in the body of the constructor).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你的第一次尝试是有效的。
在当前标准 C++03 中,这一行
被显式定义为创建一个
A
对象并复制该n
次。我相信在 C++0x 中,这被更改为创建
n
个默认构造的A
(一个小的差异)。然后您也许可以在 A 的构造函数中执行某些操作以使每个实例都唯一。现在你不能。
Your first attempt is the one that works.
In the current standard C++03 this line
is explicitly defined to create one
A
object and copy thatn
times.I belive that in C++0x this is changed to create
n
default constructedA
s (a small difference). Then you might perhaps be able to do something inA
s constructor to make each instance unique.Right now you cannot.
它被复制,因为该构造函数的签名如下:
显然,您只需将默认构造的对象传递给该构造函数,它就会复制它。
如果您想在初始化列表中进行初始化,显然您只能使用某些对象的构造函数。我想,您不想创建一个包装类只是为了初始化初始化列表中的向量,所以我们仅限于向量的构造函数。唯一看起来合理的是
因此您可以创建一个迭代器来返回所需数量的默认构造对象。
不过,我建议只在构造函数主体中进行构造。
It gets copied because that constructor's signature is as follows:
It is evident that you just pass a default-constructed object to this constructor and it copies it.
If you want to initialize in the initializer list, you are limited to constructors of some objects, obviously. I guess, you wouldn't like to create a wrapper class just to initialize the vector in initializer list, soo we are limited to vector's constructors. The only one that seems reasonable is
So you can create an iterator to return the needed number of default-constructed objects.
I suggest just constructing in the constructor body though.
正如已经评论过的,您可以使用 boost 中的 make_function_input_iterator ,如下所示:
但是请注意,当我测试代码时,我发现比您的第一个解决方案中发生了更多的复制构造/运算符=。接下来,还创建了一个附加对象(refvalue 3)(用于最后一个“停止”迭代器)。我不知道这个附加行为是否可行,但如果您确实需要的话,它可以在初始化器列表中初始化向量。
As already commented, you could use
make_function_input_iterator
from boost as follows:Note however that when I tested the code I saw a bit more copy constructing/operator= going on than in your first solution. Next to that, also an additional object (refvalue 3) was created (for the last "stop" iterator). I do not know if this additional behaviour is feasible, but it does the trick of initializing the vector in your initializer list if you really want it.