如何生成具有唯一值的向量?

发布于 2024-11-26 12:17:05 字数 1217 浏览 2 评论 0原文

我有一个将唯一对象生成到向量中的示例:

#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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

ヤ经典坏疍 2024-12-03 12:17:05

你的第一次尝试是有效的。

在当前标准 C++03 中,这一行

std::vector< A > as( n ); 

被显式定义为创建一个 A 对象并复制该 n 次。

我相信在 C++0x 中,这被更改为创建 n 个默认构造的 A (一个小的差异)。然后您也许可以在 A 的构造函数中执行某些操作以使每个实例都唯一。

现在你不能。

Your first attempt is the one that works.

In the current standard C++03 this line

std::vector< A > as( n ); 

is explicitly defined to create one A object and copy that n times.

I belive that in C++0x this is changed to create n default constructed As (a small difference). Then you might perhaps be able to do something in As constructor to make each instance unique.

Right now you cannot.

洛阳烟雨空心柳 2024-12-03 12:17:05

它被复制,因为该构造函数的签名如下:

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

因此您可以创建一个迭代器来返回所需数量的默认构造对象。

不过,我建议只在构造函数主体中进行构造。

It gets copied because that constructor's signature is as follows:

​explicit vector( size_type count,
             const T& value = T(),
             const Allocator& alloc = Allocator());

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

template <class InputIterator>

vector( InputIterator first, InputIterator last,
        const Allocator& alloc = Allocator() );

So you can create an iterator to return the needed number of default-constructed objects.

I suggest just constructing in the constructor body though.

难理解 2024-12-03 12:17:05

正如已经评论过的,您可以使用 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)(用于最后一个“停止”迭代器)。我不知道这个附加行为是否可行,但如果您确实需要的话,它可以在初始化器列表中初始化向量。

As already commented, you could use make_function_input_iterator from boost as follows:

#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);
}

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文