2

std::string クラスの機能を模倣することになっている単純なクラスを作成します (演習として!):

#ifndef _STR12_1_H
#define _STR12_1_H

#include <string>
#include <iostream>

class Str12_1
{
public:

    typedef char* iterator;
    typedef const char* const_iterator;
    typedef long size_type;


    Str12_1();
    Str12_1(const Str12_1& str);
    Str12_1(const char *p);
    Str12_1(const std::string& s);

    size_type size() const;

    //Other member functions


private:
    iterator first;
    iterator onePastLast;
    iterator onePastAllocated;
};

"new" に関連するオーバーヘッドを回避する (そして<memory>ヘッダーに慣れるため) ために、ライブラリのアロケーター テンプレート クラスを使用して文字列にメモリを割り当てることにしました。コピー コンストラクターでの使用例を次に示します。

#include <memory>
#include <algorithm>

using std::allocator;
using std::raw_storage_iterator;
using std::uninitialized_copy;


Str12_1::Str12_1(const Str12_1& str)
{
    allocator<char> charAlloc;
    first = charAlloc.allocate(str.size());
    onePastLast = onePastAllocated = first + str.size();
    *onePastLast = '\0';

    raw_storage_iterator<char*, char> it(first);

    uninitialized_copy(str.first, str.onePastLast, it);


}

コンパイラは、「uninitialized_copy」行に 2 つのエラーを表示し続けます。どちらもライブラリのヘッダーに戻ります。

error: invalid conversion from 'char' to 'char*'

error: no match for 'operator!=' in '__first != __last'

問題は、char から char* への変換がその行のどこにあるのか、同じ型 (str.first、str.onePastLast) の 2 つのポインターを "!=" と比較できない理由がわからないことです。

「new」も使えますが、前述のとおり、 で練習したいと思い<memory>ます。では、なぜこれが機能しないのか誰か教えてもらえますか?

4

1 に答える 1

5

標準を見ると、raw_storage_iteratortypedef は ではありませんvalue_typeTvoid代わりに次のようになります。

template <class OutputIterator, class T>
class raw_storage_iterator
: public iterator<output_iterator_tag,void,void,void,void>
                                      ^^^^

一方、uninitialized_copyその typedef を使用する必要があります。

template <class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_copy(InputIterator first, InputIterator last,
ForwardIterator result);

効果:

for (; first != last; ++result, ++first)
::new (static_cast<void*>(&*result))
typename iterator_traits<ForwardIterator>::value_type(*first);
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

あなたのコードでは、すべての置換の後、これは次のようになります。

new (...&*result) void (*first);
                  ^^^^^^^^^^^^^
                 invalid use here

このことから、この 2 つは決して一緒に働くことを意図していなかったと結論付けることができます。

を使用したい場合は、すべての魔法がオーバーロードで発生するため、raw_storage_iteratorに渡しても問題ありません。std::copyoperator=(const T&)

これのいずれかがプリミティブに必要であると思われる場合は、 (NB! 終了 NUL) でchar割り当てて.new char[x]strcpy

于 2011-02-01T23:02:19.407 に答える