-1

私は C++ の学習の初期段階にあり、クラスを扱っています。独自のクラスでベクターの機能を再作成した後、次のステップは、新しい Vec クラスを使用して独自のバージョンの文字列を作成することです。私はこれらすべての #includes がどのように相互作用するかを知るには新しすぎると思いますが、多くの同様の質問を検索した後、どこかに欠けているようです. しかし、必要な場所に正しいヘッダーを含めていると想定しているため、私には意味がありません。

強度

#ifndef GUARD_Str_h
#define GUARD_Str_h

#include <algorithm>
#include <iterator>

#include "Vec.h"

class Str {
public:
    typedef Vec<char>::size_type size_type;

    Str() { }

    Str(size_type n, const char& val): data(n, val) { }

    Str(const char* cp) {
        std::copy(cp, (cp + std::strlen(cp)), std::back_inserter(data));
    }
private:
    Vec<char> data;
};

#endif

Vec.h

#ifndef GUARD_Vec_h
#define GUARD_Vec_h

#include <cstring>
#include <memory>
#include <algorithm>

template <class T> class Vec {
public:
    typedef T* iterator;
    typedef const T* const_iterator;
    typedef size_t size_type;
    typedef T value_type;
    typedef std::ptrdiff_t difference_type;
    typedef T& reference;
    typedef const T& const_reference;

    Vec() { create(); } //constructor
    explicit Vec(size_type n, const T& val = T()) { create(n, val); } //constructor
    Vec(const Vec& v) { create(v.begin(), v.end()); } //copy constructor
    ~Vec() { uncreate(); } //deconstructor

    size_type size() const { return (avail - data); }

    void push_back(const T&);

    T& operator[](size_type i) { return data[i]; }
    const T& operator[](size_type i) const { return data[i]; }

    Vec& operator=(const Vec&);

    iterator begin() { return data; }
    const_iterator begin() const { return data; }
    iterator end() { return avail; }
    const_iterator end() const { return avail; }
private:
    iterator data;  //first element in the Vec
    iterator avail; //one past the last element in the Vec
    iterator limit; //one past the last availible space in the Vec

    std::allocator<T> alloc;

    void create();
    void create(size_type, const T&);
    void create(const_iterator, const_iterator);

    void uncreate();

    void grow();
    void unchecked_append(const T&);
};

template <class T> Vec<T>& Vec<T>::operator=(const Vec& v)
{
    if (v != this) {
        uncreate();

        create(v.begin(), v.end());
    }
    return *this;
}

template <class T> void Vec<T>::push_back(const T& val)
{
    if (avail == limit)
        grow();
    unchecked_append(val);
}

template <class T> void Vec<T>::create()
{
    data = avail = limit = 0;
}

template <class T> void Vec<T>::create(size_type n, const T& val)
{
    data = alloc.allocate(n);
    limit = avail = (data + n);
    std::unintialized_fill(data, avail, val);
}

template <class T> void Vec<T>::create(const_iterator beg, const_iterator end)
{
    data = alloc.allocate(end - beg);
    limit = avail = std::uninitialized_copy(beg, end, data);
}

template <class T> void Vec<T>::uncreate()
{
    if (data) {
        iterator iter = avail;
        while (iter != data)
            alloc.destroy(--iter);

        alloc.deallocate(data, (limit - data));
    }
    data = avail = limit = 0;
}

template <class T> void Vec<T>::grow()
{
    size_type new_size = std::max((2 * (limit - data)), difference_type(1));

    iterator new_data = alloc.allocate(new_size);
    iterator new_avail = std::uninitialized_copy(data, limit, new_data);

    uncreate();

    data = new_data;
    avail = new_avail;
    limit = (data + new_size);
}

template <class T> void Vec<T>::unchecked_append(const T& val)
{
    alloc.construct(avail++, val);
}

#endif

Str クラスを作成する前に、Vec クラスをテストしていたところ、すべてが正常に機能していました。Vec.h を含め、Vec をベクターの代わりに使用できました。

私が作成したこの新しい Str クラスを使用して、メイン ソース ファイルに Str.h を含めます。コンパイルすると、std::uninitialized_copy が std のメンバーではないというエラーが表示されます。私はそれがメモリヘッダーで定義されていることを知っており、インクルードをどこに置いても、それを表示する方法を理解できません。クラスが #includes と対話する方法に何か問題があると確信していますが、私は新しいです。誰かが助けてくれれば、私はそれを感謝します。

4

1 に答える 1

8

std::unintialized_fill存在しません。tの前にstd::uninitialized_filli必要です。

于 2013-01-10T20:26:52.033 に答える