7

一意のオブジェクトをベクトルに生成する次の例があります。

#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 の 1 つのオブジェクトがすべてのベクター要素にコピーされます。

すべての一意のオブジェクトを持つベクトルを作成する方法はありますか (最初の例のように)?

より明確にするために:ベクトルを含むクラスがあります。このベクトルには、すべての一意のオブジェクトが含まれている必要があります (1 つのオブジェクトのコピーではありません)。そして、コンストラクターの本体ではなく、初期化リストで初期化したいと思います。

4

3 に答える 3

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

したがって、必要な数のデフォルトで構築されたオブジェクトを返すイテレータを作成できます。

ただし、コンストラクター本体で構築することをお勧めします。

于 2011-07-28T07:26:15.787 に答える
3

あなたの最初の試みはうまくいくものです。

現在の標準 C++03 では、この行

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

A1 つのオブジェクトを作成し、その回数をコピーするように明示的に定義されていますn

C++0x では、これが変更され、nデフォルトで構築されたAs が作成されると思います (わずかな違いです)。次に、コンストラクターで何かを実行してA、各インスタンスを一意にすることができる場合があります。

今はできません。

于 2011-07-28T07:30:29.023 に答える
1

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

ただし、コードをテストしたときに、最初のソリューションよりもコピーの構築/演算子 = が少し多くなっていることに注意してください。その次に、追加のオブジェクト (参照値 3) も作成されました (最後の「停止」反復子用)。この追加の動作が実行可能かどうかはわかりませんが、本当に必要な場合は、イニシャライザ リスト内のベクトルを初期化するトリックを行います。

于 2011-07-28T09:22:16.090 に答える