简体   繁体   English

使用模板化comp函数实现unique_copy-类型推断

[英]Implementing unique_copy with templated comp function - type inference

I have implemented my version of unique_copy and it works. 我已经实现了我的unique_copy版本,并且可以正常工作。 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 . 我不喜欢的是equals函数equals<Container::iterator>必须用Container::iterator显式实例化。 I think the type might be inferred from in.begin() , which is of type Container::iterator . 我认为类型可以从in.begin()推断出来,该类型为Container::iterator I tried to declare equals as bool()(Iterator,Iterator) in the function prototype, but it failed 'orribly. 我试图在函数原型中将equals声明为bool()(Iterator,Iterator) ,但是失败了。

../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);

If you implement equals as a functor rather than as a function template, you can basically get what you want: 如果将equals作为函子而不是函数模板实现,则基本上可以得到所需的内容:

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

// ...

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

Note that because the standard library already has an equal_to functor , you should probably choose a different name that better connotes the difference between your functor and std::equal_to , eg iter_equals . 请注意,由于标准库已经具有equal_to函子 ,因此您可能应该选择一个不同的名称,以更好地表示函子和std::equal_to之间的std::equal_to ,例如iter_equals Or, better yet, you should just use std::equal_to instead of reinventing the wheel by dereferencing the iterators as you call equals instead of passing in the iterators themselves (this is what the standard library algorithms do). 或者,更好的是,您应该只使用 std::equal_to而不是通过在调用equals取消对迭代器的引用来重新发明轮子,而不是传入迭代器本身(这是标准库算法所做的事情)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM