使用模板化复合类型推理实现unique_copy

Implementing unique_copy with templated comp type inference

本文关键字:实现 推理 unique copy 类型 复合      更新时间:2023-10-16

我已经实现了我的unique_copy版本并且它可以工作。问题是我必须这样称呼它:

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

我不喜欢的是 equals 函数equals<Container::iterator>它必须用 Container::iterator 显式实例化。我认为该类型可以从in.begin()推断出来,该类型属于Container::iterator类型。我试图在函数原型中将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>);
                                                                               ^

这是代码:

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<<" ";});
}

这就是我想要的:

my_unique_copy(in.begin(), in.end(), out.begin(), equals);
如果你把

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{});

请注意,由于标准库已经有一个equal_to函子,因此您可能应该选择一个不同的名称,以更好地表示函子和std::equal_to之间的区别,例如 iter_equals .或者,更好的是,您应该只使用 std::equal_to 而不是通过取消引用调用的迭代器来重新发明轮子equals而不是传入迭代器本身(这就是标准库算法所做的)。