2011-02-01 71 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就可以完成这一任务。

相关问题