I wan't use the multimap on my own templated class.
The following is a working example with a builtin type.

int dat[5] = {0,6,3,7,3};
  
 typedef std::multimap< int, int >  asso;
 asso dict;
 for (int i=0;i<5;i++){
   dict.insert(make_pair(dat[i],i));
 }
  
  asso::iterator pos;
  
  for(pos=dict.begin(); pos!=dict.end() ;pos++)
    cout << pos->first <<" next "<< pos->second <<endl;

This is my non-working code with my own templated type.

template<typename T>
void test(Array<T> ai){
  typedef std::multimap< Array<T>, int >  asso;
  asso dict;
  for (int i=0 ; i<5 ; i++){
   dict.insert(make_pair(ai(i),i));
  }
  
  asso::iterator pos;
  
  for(pos=dict.begin() ; pos!=dict.end() ; pos++)
    cout << pos->first <<" next "<< pos->second <<endl;
}

Where my own templated type is called 'Array<T>'.

I think the problem is related to the std::multimap using iterators,
and I've never really understood iterators, and even less how to write my own iterators for my own templates.
This is my iterator definitions and implementation in my class

typedef T              value_type;
  typedef T*             iterator;
  typedef const T*       const_iterator;
  typedef T&             reference;
  typedef const T&       const_reference;
  typedef std::size_t    size_type;
  typedef std::ptrdiff_t difference_type;
  
        // iterator support
  iterator begin() { return data_; }
  const_iterator begin() const { return data_; }
  iterator end() { return data_+x_; }
  const_iterator end() const { return data_+x_; }

thanks in advance

Recommended Answers

All 5 Replies

You're paraphrasing, based on where you think the problem is, and the end result is that you haven't provided enough information for people to help.

You haven't explained what you mean by "non-working". Does the code fail to compile? Or does it compile, but fail to link? Or does it compile and link, but run incorrectly?

The code you've shown does not use the iterators from your Array class: it uses iterators from the multimap class.

Making a stab in the dark, I'd guess your problem is that your Array class needs you to implement a copy constructor and/or assignment operator.

Sorry for not elaborating.
this is the header for my class

template<typename T>
class Array {
 public:
  /*
    arrayconstructors
    1. copy constructor
    2. read from file constructor without delim
    3. read from file constructor with delim
    4. dimension constructor
    5. data constructor
   */
  
  //iterator support
  // type definitions
  
  typedef T              value_type;
  typedef T*             iterator;
  typedef const T*       const_iterator;
  typedef T&             reference;
  typedef const T&       const_reference;
  typedef std::size_t    size_type;
  typedef std::ptrdiff_t difference_type;
  
        // iterator support
  iterator begin() { return data_; }
  const_iterator begin() const { return data_; }
  iterator end() { return data_+x_; }
  const_iterator end() const { return data_+x_; }
  /*
  typedef T* iterator;
  typedef const T* const_iterator;
  typedef T& reference;
  iterator begin() {return data_;}
  const_iterator begin() const {return data_;}
  iterator end() {return data_+x_;}
  const_iterator end() const {return data_+x_;}
  */


  Array(const Array<T>& var);
  Array(std::string str,std::string delims);
  Array(std::string str) ;
  Array(uint length);
  Array(T* d,uint a);
  ~Array()/// Only tries to free memory if length of Array is bigger than one.
  {if(x_!=0){delete [] data_;}}

  /*
    simple accessors and mutators
   */
  ///Returns the length of the array.
  uint length() const                  { return x_;/// @return Gives the length of
the array.   
  }
  T& operator() (uint r); //inlined 
  T operator() (uint r) const; //inlined

  /*
     These crazy definitions are requried since
     Array<U> cannot access internals of Array<T>
     So methods requiring internals should be friends
     
     This is comparison operators and extractors
   */
  //first declarations
  Array<char> operator& (const Array<T> &f);///< A keeplist using bitwize AND '&'.
  Array<char> operator| (const Array<T> &f);///< A keeplist using bitwize OR '&'.
  Array<char> operator< (const float &f);///< A keeplist using comparison '<' and a
float value.
  Array<char> operator> (const float &f);///< A keeplist using comparison '>' and a
float value.
  Array<char> operator== (const float &f);///< A keeplist using comparison '==' and
a float value.
  Array<char> operator< (const Array<T> &f);///< A keeplist using comparison '<' and
another Array<T>.
  Array<char> operator> (const Array<T> &f);///< A keeplist using comparison '>' and
another Array<T>.
  Array<char> operator== (const Array<T> &f);///< A keeplist using comparison '=='
and another Array<T>.


  /// Will extract values from Array given a keeplist.
  Array<T> extract(const Array<char> &other);
  Array<T> exchange(const Array<int> &other);
  //then friend declare them
  template <typename U>
  friend Array<char> Array<U>::operator< (const float &f);
  template <typename U>
  friend Array<char> Array<U>::operator> (const float &f);
  template <typename U>
  friend Array<char> Array<U>::operator== (const float &f);
  template <typename U>
  friend Array<U> Array<U>::extract(const Array<char> &other);
  template <typename U>
  friend Array<U> Array<U>::exchange(const Array<int> &other);
  template <typename U>
  friend Array<char> Array<U>::operator< (const Array<U> &f);
  template <typename U>
  friend Array<char> Array<U>::operator> (const Array<U> &f);
  template <typename U>
  friend Array<char> Array<U>::operator== (const Array<U> &f);
  template <typename U>
  friend Array<char> Array<U>::operator& (const Array<U> &f);
  template <typename U>
  friend Array<char> Array<U>::operator| (const Array<U> &f);
    


  /// Will input vals in array given a keeplist.
  void set_values(const Array<char> &indicator, T vals);
  /// Will fill up array with value=var.
  void fillUp(T var) {for(int i=0;i<x_;i++) data_[i]=var;}
  Array<T> rev();
  void random(T lowest, T highest);
  ///Should only be used on a keeplist=Array<char>, to get the sum of true values. 
  int numTrues() const {return numOnes_;}

  ///Function used for outputting the the Array to a iostream.
  std::ostream& dump(std::ostream &o=(std::cout),char sep=' ') const;
  
  
  /*
    Basic overloaded mathfunctions
    these allocates a new Array<T> for the result
   */
  
  Array<T> operator! ();///< Returns the bool complement of all elements in Array.
  Array<T> operator- (); ///< Returns the '-Array', that is '0-Array'.  
  Array<T> operator/ (const double &other);///< Normal math divisor.
  Array<T>operator+( const double f ); ///< Allows user to use '+' with scalar doubles.
  Array<T> operator+ (const Array<T>&);///< Allows user to use '+' with another 
Array<T>.
  Array<T>operator-( const double f );///< Allows user to use '-' with scalar doubles.
  Array<T> operator- (const Array<T>&);///< Allows user to use '-' with another
Array<T>.
  

  //Will assign a copy of righthandsign to Array at lefthand sign.
  Array<T>& operator= (const Array<T>&);
  
  ///Will change value in callee, just an example of low-mem operations. 
  void plus(const Array<T>&);
  T *data();
  int numOnes_;///< The number of TRUE values in a keeplist.
private:
  uint x_;///< The number of elments in Array.
  
  T*  data_;///< The c-style array that contain the data.
  
  void readarray(std::string filename,const std::string delims);
  void typecast_stringarray(const std::vector<std::string> &tok);///< Used for
typecasting the tokenized string from a file.
};

Everything in this header is implemented and is working, so far I can tell


this is the compile error

test.cpp: In function ‘void tes(Array<U>)’:
test.cpp:20: error: expected `;' before ‘pos’
test.cpp:22: error: ‘pos’ was not declared in this scope
test.cpp: In function ‘void tes(Array<U>) [with T = int]’:
test.cpp:31:   instantiated from here
test.cpp:20: error: dependent-name ‘std::asso::iterator’ is parsed as a
non-type, but instantiation yields a type
test.cpp:20: note: say ‘typename std::asso::iterator’ if a type is meant
/usr/include/c++/4.2/bits/stl_function.h: In member function ‘bool
std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = Array<int>]’:
/usr/include/c++/4.2/bits/stl_tree.h:894:   instantiated from ‘typename
std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_equal(const
_Val&) [with _Key = Array<int>, _Val = std::pair<const Array<int>, int>, _KeyOfValue
= std::_Select1st<std::pair<const Array<int>, int> >, _Compare =
std::less<Array<int> >, _Alloc = std::allocator<std::pair<const Array<int>, int>
>]’
/usr/include/c++/4.2/bits/stl_multimap.h:340:   instantiated from ‘typename
std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const
_Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp>
>::other>::iterator std::multimap<_Key, _Tp, _Compare, _Alloc>::insert(const
std::pair<const _Key, _Tp>&) [with _Key = Array<int>, _Tp = int, _Compare =
std::less<Array<int> >, _Alloc = std::allocator<std::pair<const Array<int>, int>
>]’
test.cpp:17:   instantiated from ‘void tes(Array<U>) [with T = int]’
test.cpp:31:   instantiated from here
/usr/include/c++/4.2/bits/stl_function.h:227: error: passing ‘const Array<int>’
as ‘this’ argument of ‘Array<char> Array<T>::operator<(const Array<T>&) [with
T = int]’ discards qualifiers
/usr/include/c++/4.2/bits/stl_tree.h:894:   instantiated from ‘typename
std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_equal(const
_Val&) [with _Key = Array<int>, _Val = std::pair<const Array<int>, int>, _KeyOfValue
= std::_Select1st<std::pair<const Array<int>, int> >, _Compare =
std::less<Array<int> >, _Alloc = std::allocator<std::pair<const Array<int>, int>
>]’
/usr/include/c++/4.2/bits/stl_multimap.h:340:   instantiated from ‘typename
std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const
_Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp>
>::other>::iterator std::multimap<_Key, _Tp, _Compare, _Alloc>::insert(const
std::pair<const _Key, _Tp>&) [with _Key = Array<int>, _Tp = int, _Compare =
std::less<Array<int> >, _Alloc = std::allocator<std::pair<const Array<int>, int>
>]’
test.cpp:17:   instantiated from ‘void tes(Array<U>) [with T = int]’
test.cpp:31:   instantiated from here
/usr/include/c++/4.2/bits/stl_function.h:227: error: cannot convert
‘Array<char>’ to ‘bool’ in return

The first error message is referring to std::size_t and (presumably) std::ptrdiff_t types not being declared. You need to #include standard headers that declare them.

Other messages are telling you about the need to add "typename" to some of your declarations (presumably typedefs).

Your header - at least the way you've shown it - only declares constructors (and various other member functions of your class), and does not implement them.

Taken literally, the error messages you've shown are indicating a problem with comments (eg an error reported for line 31, but line 31 is commented out) Which suggests those error messages do not correspond to the header file you've provided.

Your list of error messages also has atypical characters in it (eg ‘) which makes the messages hard to read.

Accordingly, I gave up on trying to make more sense of your problem.

Ok,
I was just trying to avoid an information overload for people trying to make sense of my problem,
Attached is the a RMatrix.cpp with contains the header and the implementation,
The file called test.cpp is the error prone codesnippet.

thanks in advance

Hi I managed to nail this one down myself.

Whenever you define an iterator that depends on a templated type,
you have to use keyword typename infront.

like this

template<typename T>
void test(Array<T> ai){
  typedef std::multimap< T, int >  asso;
  asso dict;
  for (int i=0 ; i<5 ; i++){
   dict.insert(make_pair(ai(i),i));
  }
  
  typename std::multimap<T, int>::iterator pos;
  
  for(pos=dict.begin() ; pos!=dict.end() ; pos++)
    cout << pos->first <<" next "<< pos->second <<endl;
}

thanks for your help

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.