user3925365
user3925365

Reputation: 37

operator overloading in templates

I am trying to use std::find algorithm & my third argument is object of type MyPair that has overloaded == operator. But the problem is its not getting called. Here is my code:

MyPair.h

template<class K, class V> class MyPair;

template<class K,class V> 
bool operator==(const MyPair<K,V>& p1, const MyPair<K,V>& p2);

template<class K,class V>
class MyPair:public std::pair<K,V>
{
public:
    MyPair(){};

    MyPair(const K&x, const V& y) :pair<K, V>(x, y){ cout << "ctor"<< endl; }

    template<class K, class V>
    friend bool operator==<>(const MyPair<K, V>& p1, const MyPair<K, V>& p2) { 
           cout<<"called"; return true; }
};

another file I am using std::find algo

void WordVector::insert(string word){
    MyPair<string, int> p(word, 1);
    auto iter = find(wordvec.begin(),wordvec.end(),p);

    if (iter == wordvec.end()){
        wordvec.push_back(p);
    }
    else{
        ++iter->second;

    }
}

Upvotes: 0

Views: 103

Answers (2)

Tobias
Tobias

Reputation: 5198

The following code works for me with g++ 4.8.3:

EDIT: To declare operator == and define it right afterwards was pretty senseless. Therefore, I shifted the definition of the operator behind the definition of MyPair. Also this works with g++.

#include <string>
#include <vector>
#include <algorithm>
#include <iostream>

template<class K, class V> class MyPair;

template<class K,class V> 
bool operator==(const MyPair<K,V>& p1, const MyPair<K,V>& p2);

template<class K,class V>
class MyPair:public std::pair<K,V>
{
public:
    MyPair(){};

    MyPair(const K&x, const V& y) : std::pair<K, V>(x, y){ std::cout << "ctor\n"; }

    friend bool operator==<>(const MyPair<K, V>& p1, const MyPair<K, V>& p2);
};

template <class K, class V>
bool operator==(const MyPair<K, V>& p1, const MyPair<K, V>& p2) { 
    std::cout<<"called"; return true;
}

//another file I am using std::find algo
class WordVector {
    std::vector<MyPair<std::string,int> > wordvec;
public:
    void insert(const std::string& word);
};

void WordVector::insert(const std::string& word){
    MyPair<std::string, int> p(word, 1);
    auto iter = find(wordvec.begin(),wordvec.end(),p);

    if (iter == wordvec.end()){
        wordvec.push_back(p);
    }
    else{
        ++iter->second;

    }
}

int main() {
    WordVector wv;

    wv.insert("first");
    wv.insert("second");


    return 0;
}


/**
     Local Variables:
     compile-command: "g++ -std=c++11 test.cc -o test.exe && ./test.exe"
     End:
 */

The output is:

g++ -std=c++11 test.cc -o test.exe && ./test.exe
ctor
ctor
called
Compilation finished at Sat Aug  9 18:31:36

With the modification

template<class K,class V>
class MyPair:public std::pair<K,V>
{
public:
    MyPair(){};

    MyPair(const K&x, const V& y) : std::pair<K, V>(x, y){ std::cout << "ctor\n"; }

    template<class K, class V>
    friend bool operator==<>(const MyPair<K, V>& p1, const MyPair<K, V>& p2) { 
        std::cout<<"called"; return true; }

};

which fits better the original I get the following error messages and warnings:

g++ -std=c++11 test.cc -o test.exe && ./test.exe
test.cc:19:12: error: declaration of 'class K'
  template <class K, class V>
            ^
test.cc:11:10: error:  shadows template parm 'class K'
 template<class K,class V>
          ^
test.cc:19:21: error: declaration of 'class V'
  template <class K, class V>
                     ^
test.cc:11:18: error:  shadows template parm 'class V'
 template<class K,class V>
                  ^
test.cc:20:73: error: defining explicit specialization 'operator==<>' in friend declaration
  friend bool operator==<>(const MyPair<K, V>& p1, const MyPair<K, V>& p2)
                                                                         ^

Compilation exited abnormally with code 1 at Sat Aug  9 18:37:40

which are quite descriptive.

Upvotes: 0

YYJo
YYJo

Reputation: 1734

If you're just trying to find some specific pair why not just use find_if with an appropriate predicate ?

E.g (demo):

#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>

using namespace std;

int main() {
    vector<pair<int,int> > a = { {1,1} , {1,2}, {1,3}};

    auto res = find_if(a.begin(), a.end(), 
                    [](pair<int,int> p){ return (p.first == 1 && p.second==3);});
    cout<< (*res).first;
    return 0;
}

Upvotes: 2

Related Questions