2011-02-01 89 views
2

我構建應該模仿std :: string類的功能的簡單類(作爲練習!):C++:爲什麼我不打電話給「std :: uninitialized_copy」工作?

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

爲了避免與相關聯的開銷「新」(和增加我熟悉<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」線,既引回庫中的頭兩個錯誤,:

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

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

問題是我不明白char到char *的轉換是什麼,以及爲什麼兩個相同類型的指針(str.first,str.onePastLast)不能與「!=」進行比較。

我可以使用「新」,但如前所述,我想與<memory>練習。那麼有人可以告訴我爲什麼這不起作用嗎?

+2

默認分配器只是在引擎蓋下調用`new`。它沒有魔法。它允許用戶通過提供不同的分配器來定製內存分配策略。但是默認的和'new`完全相同。只是想你可能想知道,即使它不回答你的問題:) – jalf 2011-02-01 22:02:28

+0

你確定嗎?我從Accelerated C++和其他在線資源中收集到的是,「new」在分配空間後調用類型的默認構造函數,而「.allocate」則不會。 – Kevin 2011-02-01 22:28:34

回答

5

望着標準raw_storage_iterator沒有的typedef value_typeT,但它是void代替:

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 

從您可以得出結論,這兩個從來沒有打算一起工作。

如果你想使用raw_storage_iterator,那麼應該可以將它傳遞給std::copy,因爲所有的魔法都發生在operator=(const T&)過載中。

如果您認爲對於像char這樣的原始設備,您可能只需分配new char[x](注意!終止NUL)並複製strcpy就可以完成這一任務。

相關問題