-1

I am creating a C++ wstring class for use with mingw version 4.3.0, cross-compiling for Win32. I want my string to work like std::string which means that I want an erase(int pos) method that erases a single element at position pos.

Here is my first attempt:

#include <wchar.h>
#include <iostream>
#include <vector>

class wstring : public std::vector<wchar_t>{
public:
    void erase(size_t where){
    erase(begin()+where);
    }
};

int main(int argc,char **argv) {
    wstring c1;
    c1.push_back(L'a');
    c1.push_back(L'b');
    c1.push_back(L'c');
    c1.erase(1);

    for(size_t i = 0;i<c1.size();i++){
    std::cout << "c1[" << i << "] = " << c1[i] << "\n";
    }
    return 0;
}

This looks like it should work to me, but I get this wacko compiler error when I try to compile it:

$ i386-mingw32-g++ x1.cpp
x1.cpp: In member function 'void wstring::erase(size_t)':
x1.cpp:8: error: no matching function for call to 'wstring::erase(__gnu_cxx::__normal_iterator<wchar_t*, std::vector<wchar_t, std::allocator<wchar_t> > >)'
x1.cpp:7: note: candidates are: void wstring::erase(size_t)
$ 

What's really weird is that if I take out the erase method and just inline the code, I have no problem:

#include <wchar.h>
#include <iostream>
#include <vector>

class wstring : public std::vector<wchar_t>{
};

int main(int argc,char **argv) {
    wstring c1;
    c1.push_back(L'a');
    c1.push_back(L'b');
    c1.push_back(L'c');
    c1.erase(c1.begin()+1);

    for(size_t i = 0;i<c1.size();i++){
    std::cout << "c1[" << i << "] = " << c1[i] << "\n";
    }
    return 0;
}

I'm mystified.

vy32
  • 28,461
  • 37
  • 122
  • 246
  • I thought you called your method `remove` -- why isn't it `c1.remove(1)`? – Kerrek SB Jul 04 '11 at 23:36
  • Oh, also don't derive from standard library containers! And is there a reason you can't use `std::basic_string`? – Kerrek SB Jul 04 '11 at 23:37
  • I fixed the demo program. My method is supposed to be called erase(), as I'm trying to add new erase() method that works like the `std::string` erase and allows you to erase by offset. – vy32 Jul 05 '11 at 01:24
  • Deriving from std::baseic_string is an interesting idea. In fact, that solved my problem! Why don't you list that as an answer and I will accept it. – vy32 Jul 05 '11 at 01:25
  • You "fixed" it the wrong way -- now you have `erase` in your class and in the base class! Why not leave it at `remove` as you had it originally and just fix the invocation? – Kerrek SB Jul 05 '11 at 01:27
  • Seriously, don't derive from standard library types! (There are exceptions, like... exceptions, and iterators, but never from heavy-weight classes.) – Kerrek SB Jul 05 '11 at 01:29
  • @vy: You should probably accept David's answer if you go with `std::wstring`, since he already said it. – Kerrek SB Jul 05 '11 at 01:36

2 Answers2

5

The answer to your particular question is to use std::vector<T>::erase( iterator ) instead of remove:

std::vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
v.push_back( 3 );
v.erase( v.begin()+1 ); // equivalent to v.remove( 1 )

But I don't think that you are barking at the right tree. There is already a std::wstring in the standard library that is the instantiation of basic_string with wchar_t, and that will get as close as it can to std::string (which is an instantiation of the same template with char)

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • 1
    +1 for the wrong tree, and if I could +1 again for suggesting std::wstring, I would. – David Hammen Jul 04 '11 at 23:33
  • There is no std::wstring in the mingw STL. – vy32 Jul 05 '11 at 01:21
  • @vy32: Are you sure? It should. I don't have an older version to test with, but in mingw 4.5.2 there certainly is a `std::wstring` in ``. If nothing else, are you unable to use `std::basic_string`? – James McNellis Jul 05 '11 at 01:26
  • Gosh, I'm an idiot. You are right, there is a wstring. It's just not in the #include directory where I was grepping. Sigh. – vy32 Jul 05 '11 at 01:43
  • Learning the STL by grep-ing in the include directory might not be the best idea. You might consider some short of book or tutorial as a easier path into learning. – David Rodríguez - dribeas Jul 05 '11 at 07:28
1

You could always just use the existing type std::wstring, which is a typedef for std::basic_string<wchar_t>. Feel free to make other string classes based on your favourite integral types, too.

Note that there are corresponding stream objects std::wcout etc.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084