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

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

Attachments
/*
 * 23/9 2008 thorfinn@binf.ku.dk
 * This is STL implementation of an Array/Matrix class
 * @author Thorfinn Sand thorfinn@binf.ku.dk
*/


/*
  23/9 2008 thorfinn@binf.ku.dk
  This is STL implementation of an Array/Matrix class
 
  0. small usefull general functions 
  1. class definition of Array<T>
  2. class definition of Matrix<T>
  3. implementation of Array<T>
  4. implementation of Matrix<T>
  5. Small free functions used for operator overloading
  ------------------------------------------------------
  To disable bound check change pre-processor flag: do_bound_check
  To disable dimension info on IO, change pre-processor flag: info
  To disable value initialization of datatypes change pre-processor flag: value_initialize
 */



#pragma once

#define do_bound_check 1 ///< Toggle for disabling bound checks.
#define info 1 ///< Toggle for disabling dimension of datastructures on printout. 
#define value_initialize 1 ///< Toggle for disabling datastructures to start with default values.

#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
#include <sys/stat.h> 


/* 
   These are some free functions,
   Not related to any class but used by some member methods.
   These take primitive c++ standard in-/outputs {int, strings, float, double}
 */


/// Checking for file existence, using stat.h.
int fexists(std::string str){///@param str Filename given as a string.
  struct stat buffer ;
  return (stat(str.c_str(), &buffer )==0 ); /// @return Function returns 1 if file exists.
}

///Converts a integer type to string.
std::string to_string(int a){///@param a An integer to convert.
  std::string str;
  std::stringstream ss;
  ss<<a;
  if(!(ss>>str)){
    printf("Error converting :%d will exit\n",a);
    exit(0);
  }
  ss>>str;
  return str; ///@return Returns the string value.
}

///Converts a string to integer type.
int to_int(std::string a){///@param a a String to convert.
  int str;
  float check;
  std::stringstream ss;
  std::stringstream ss2;
  ss<<a;
  if(!(ss>>str)){
    printf("Error converting :\"%s\" will exit\n",a.c_str());
    exit(0);
  }

  //now check if numberis really an int
  ss2<<a;
  if(!(ss2>>check)){
    printf("Error converting :\"%s\" will exit\n",a.c_str());
    exit(0);
  }

  if(check!=str){
    printf("String you want as in integer is not really an integer: \"%s\"\n",a.c_str());
    puts("Just a warning");
  }

  return str;///@return Function returns the integer value.
}

///Convert string to float.
float to_float(std::string a){///@param a is the string to convert.
  float str;
  std::stringstream ss;
  ss<<a;
  if(!(ss>>str)){
    printf("Error converting :\"%s\" will exit\n",a.c_str());
    exit(0);
  }
  ss>>str;
  return str;///@return The float value.
}

///convert string to double
double to_double(std::string a){///@param a is the string to convert.
  double str;
  std::stringstream ss;
  ss<<a;
  if(!(ss>>str)){
    printf("Error converting :\"%s\" will exit\n",a.c_str());
    exit(0);
  }
  ss>>str;
  return str;///@return The double value.
}


/*
  Mother-of-all string tokenizers
  1. args = string to be splittet
  2. args = a vector<string> reference that will contain the splittet string
  3. args = delimiter list in a string like 
  
  get_lexemes(STRING_TO_SPLIT,RESULTS_STRING_VECTOR,DELIM=" \t:,;")
  this will split on whitespace,tab,colons,comma and semicolons
  return value will be number of elems tokenized
*/
///Mother-of-all string tokenizers! Function will split a string from a given set of delimiters.
int get_lexemes(std::string str,std::vector<std::string> &lexems,const std::string delims){
  ///@param str The string to be splittet.
  ///@param lexems A reference to a list of strings in which the splittet string will be put as seperate elements. A queue.
  ///@param delims A string containing all the chars that the function will split by.
  char *token = strtok( const_cast<char*>( str.c_str() ),delims.c_str());
  int numToks = 0;
  while ( token != NULL ){
    numToks++;
    lexems.push_back( token);
    token = strtok( NULL,delims.c_str() );
  }
  return numToks;///@return The number of strings that has been splittet.
}




/* This is a templated c++ array class
  * Array<char> is treated internally as an (int)
  * when doing comparisons <char> is used.  {0,1}
  * @author Thorfinn Korneliussen thorfinn@binf.ku.dk
  */

/*! \class Array
 * \brief Templated class that bare som resemblence to stl vector type.
 */ 

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


/*
  header for Matrix
 */

/*
  templated Matrix class
  <char> is treated internally as an (int)
  when doing comparisons <char> is used.  {0,1}
 */


/** This is a templated c++ Matrix class
  * Matrix<char> is treated internally as an (int)
  * when doing comparisons <char> is used.  {0,1}
  * @author Thorfinn Korneliussen thorfinn
#include <iostream>

#include <map>
#include <iterator>
#include <string>

#include "RMatrix.cpp"
using namespace std;


template<typename T>
void tes(Array<T> ai){
  int is[]={1,3,5,3,5};
  typedef std::multimap<Array<T>, int >  asso;
  //typedef std::multimap< int, int >  asso; //this works
  asso dict;
  for (int i=0;i<5;i++){
    dict.insert(make_pair(ai(i),i));
  }
  
  asso::iterator pos; //this is the problem
  
  for(pos=dict.begin(); pos!=dict.end() ;pos++)
    cout << pos->first <<" next "<< pos->second <<endl;
  
  
}

int main(){
  Array<int> ai(10);
  tes(ai);
}

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

This article has been dead for over six months. Start a new discussion instead.