deepesh
deepesh

Reputation: 53

Compilation error due to wrong choice of outputiterator for a set container

template < class ProteinTypeInfo >
 class T_PP_edge{
 private:
   std::pair<ProteinTypeInfo, ProteinTypeInfo> paired_info;
   unsigned priority;

public:
 // the constructor stores the Protein types in lexico ordering
    T_PP_edge(ProteinTypeInfo one, ProteinTypeInfo two){
    if (one<two) {paired_info.first = one; paired_info.second = two; } 
    else         {paired_info.first = two; paired_info.second = one; }
    priority = 0;
    }

  T_PP_edge& operator=(T_PP_edge& other){
   priority = other.priority;
   paired_info.first = other.paired_info.first;
   paired_info.second = other.paired_info.second;
   return *this ;
   }

   bool operator<(const T_PP_edge& a)const{
     if((*this).paired_info.first < a.paired_info.first) return true;
     else if((*this).paired_info.second < a.paired_info.second) return true;
     else return false;
   }

  const std::pair<ProteinTypeInfo, ProteinTypeInfo>& get_paired_info()const{
    return paired_info;}

 unsigned get_priority()const{return priority;}
 void set_priority(unsigned p) {priority = p;}
 };

// The lexico ordering used to compare pairs of proteins


template < class ProteinTypeInfo >
struct T_PP_edge_lexico_cmp{
public:
 typedef T_PP_edge<ProteinTypeInfo> PP_edge;
 bool operator()(const PP_edge& a, const PP_edge& b)const{
 if(a.get_paired_info().first < b.get_paired_info().first) return true;
 else if(a.get_paired_info().second < b.get_paired_info().second) return true;
 else return false;
 }

};

typedef std::string Protein_type;
typedef T_PP_edge<Protein_type> PP_edge;
typedef T_PP_edge_lexico_cmp<Protein_type> PP_edge_lexico_cmp;

int main(){
  typedef std::set<PP_edge, PP_edge_lexico_cmp> Edge_set;
  typedef Edge_set::iterator set_iterator;
  Edge_set edgeP_set, edgeR_set;
  PP_edge e1("aa", "bb"), e2("aa", "cc"), e3("bb", "cc");
  PP_edge e4("aa", "dd"), e5("aa", "cc"), e6("bb", "cc");
  edgeP_set.insert(e1); edgeP_set.insert(e2); edgeP_set.insert(e3);
  edgeR_set.insert(e4); edgeR_set.insert(e5); edgeR_set.insert(e6);
  Edge_set result;
  std::set_intersection(edgeP_set.begin(), edgeP_set.end(), edgeR_set.begin(), 
  edgeR_set.end(), result.begin());
  set_iterator itb = result.begin(), ite = result.end();

  for(; itb != ite; ++itb)
     std::cout << itb->get_paired_info().first << "-" << itb->get_paired_info().second <<  "\n";

  return 0;
  }            

Note: Include algorithm for set_intersection function.

Above code gives the following error on compilation :

g++ test_code.cpp
In file included from /usr/lib/gcc/i686-redhat-linux/4.5.1/../../../../include/c++/4.5.1/algorithm:63:0,
                 from test_code.cpp:4:
/usr/lib/gcc/i686-redhat-linux/4.5.1/../../../../include/c++/4.5.1/bits/stl_algo.h: In function ‘_OIter std::set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter) [with _IIter1 = std::_Rb_tree_const_iterator<T_PP_edge<std::basic_string<char> > >, _IIter2 = std::_Rb_tree_const_iterator<T_PP_edge<std::basic_string<char> > >, _OIter = std::_Rb_tree_const_iterator<T_PP_edge<std::basic_string<char> > >]’:
test_code.cpp:79:111:   instantiated from here
/usr/lib/gcc/i686-redhat-linux/4.5.1/../../../../include/c++/4.5.1/bits/stl_algo.h:5648:6: error: no match for ‘operator=’ in ‘__result.std::_Rb_tree_const_iterator<_Tp>::operator* [with _Tp = T_PP_edge<std::basic_string<char> >, const _Tp& = const T_PP_edge<std::basic_string<char> >&]() = __first1.std::_Rb_tree_const_iterator<_Tp>::operator* [with _Tp = T_PP_edge<std::basic_string<char> >, const _Tp& = const T_PP_edge<std::basic_string<char> >&]()’
test_code.cpp:21:14: note: candidate is: T_PP_edge<ProteinTypeInfo>& T_PP_edge<ProteinTypeInfo>::operator=(T_PP_edge<ProteinTypeInfo>&) [with ProteinTypeInfo = std::basic_string<char>, T_PP_edge<ProteinTypeInfo> = T_PP_edge<std::basic_string<char> >]

Compilation exited abnormally with code 1 at Mon Nov 26 21:28:38

I suspect this is probably due to const incorrectness in assignment operator. Kindly help me out. Thanks.

Upvotes: 1

Views: 220

Answers (1)

pmr
pmr

Reputation: 59841

result.begin() is not an OutputIterator as expected by set_intersection.

Use

std::inserter(result, result.end())

Even if result.begin() would work out it would usually just segfault. Try it with a std::vector without reserving enough memory.

And, please, for the sake of your readers: Get rid of the whitespace. Use meaningful whitespace to show the logical flow of your program.

Also, your operator= is unnecessary. It does the same as the default generated one.

Upvotes: 4

Related Questions