代码之家  ›  专栏  ›  技术社区  ›  Slazer

用模板化comp函数类型推理实现unique_copy

  •  0
  • Slazer  · 技术社区  · 9 年前

    我已经实现了我的版本 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() ,类型为 容器::迭代器 .我试图申报 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);
    
    1 回复  |  直到 9 年前
        1
  •  2
  •   ildjarn    9 年前

    如果您实施 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{});
    

    请注意,因为标准库 already has an equal_to functor ,您可能应该选择一个不同的名称,以更好地表示函子和 std::equal_to ,例如。 iter_equals 。或者,更好的是,你应该 使用 标准::等于 而不是像您所调用的那样通过取消引用迭代器来重新创建轮子 等于 而不是传递迭代器本身(这是标准库算法所做的)。