lundi 25 janvier 2016

Implementing unique_copy with templated comp function - type inference

I have implemented my version of unique_copy and it works. The problem is that I have to call it this way:

my_unique_copy(
    in.begin(),                 // ok
    in.end(),                   // ok
    out.begin(),                // ok
    equals<Container::iterator> // <--sucks
);

What I don't like is the equals function equals<Container::iterator> has to be explicitly instantiated with Container::iterator. I think the type might be inferred from in.begin(), which is of type Container::iterator. I tried to declare equals as bool()(Iterator,Iterator) in the function prototype, but it failed 'orribly.

../untitled2/main.cpp:20:32: error: 'parameter' declared as function returning a function
        bool()(Iterator,Iterator) equals){
                                ^
../untitled2/main.cpp:20:34: error: expected ')' before 'equals'
        bool()(Iterator,Iterator) equals){
                                  ^
../untitled2/main.cpp:20:34: error: expected initializer before 'equals'
../untitled2/main.cpp: In function 'int main()':
../untitled2/main.cpp:41:79: error: 'my_unique_copy' was not declared in this scope
     my_unique_copy(in.begin(),in.end(),out.begin(),equals<Container::iterator>);
                                                                               ^

This is the code:

template <typename Iterator>
bool equals(Iterator fst, Iterator snd){
    return *fst==*snd;
}

bool myfunction (int i, int j) {
  return (i==j);
}

template <typename Iterator, typename Comparator>
void my_unique_copy(Iterator begin,
       Iterator end,
       Iterator out_begin,
       Comparator equals){
    if (begin==end){
        return;
    }

    *out_begin=*begin;
    ++begin;

    while (begin!=end){
        if (!equals(out_begin, begin)){
            *(++out_begin)=*begin;
        }
        ++begin;
    }
}

int main(){
    using Container = vector<int>;
    Container in{1,2,2,3};
    Container out(4);

    my_unique_copy(in.begin(),in.end(),out.begin(),equals<Container::iterator>);
    for_each(out.begin(), out.end(), [](int v){cout<<v<<" ";});

    cout<<endl;

    unique_copy(in.begin(),in.end(),out.begin(),myfunction);
    for_each(out.begin(), out.end(), [](int v){cout<<v<<" ";});
}

This is what I want:

my_unique_copy(in.begin(), in.end(), out.begin(), equals);

Aucun commentaire:

Enregistrer un commentaire