为什么尝试存储指向函数模糊的指针

时间:2016-02-27 19:28:47

标签: c++ function c++11

这是我的代码:

    #include <functional>
    #include <iostream>
    #include<vector>

    using namespace std;

    // vector iterator
    template <class T> class vit
    {
            private:
            //vector<T>::iterator it;
            vector<T> m_v;
            function<bool (T, T)> m_fptr;
            int len, pos;
            public:
            vit(vector<T> &v) { this->m_v = v; len = v.size(); pos = 0;};
           //       it= v.begin(); };
            bool next(T &i) {
                    //if(it == m_v.end()) return false;
                    if(pos==len) return false;
                    //i = *it;
                    i = m_v[pos];
                    //if(idle) { idle = false ; return true; }
                    //it++;
                    pos++;
                    return true;};
            //bool idle = true;
            void set_same(function<bool (T,T)> fptr) { m_fptr = fptr ;};
            //void set_same(function<bool(int, int)> fun) { return ; }
            bool grp_begin() {
                    return pos == 0 || ! m_fptr(m_v[pos], m_v[pos-1]); };
            bool grp_end() {
                    return pos == len || ! m_fptr(m_v[pos], m_v[pos+1]); };
    };


    bool is_same(int a, int b) { return a == b; }

    main()
    {
            vector<int>  v ={ 1, 1, 2, 2, 2, 3, 1, 1, 1 };
            int total;
            for(auto it = v.begin(); it != v.end(); it++) {
                    if(it == v.begin() || *it != *(it-1)) {
                            total = 0;
                    }

                    total += *it;

                    if(it+1 == v.end() || *it != *(it+1)) {
                            cout << total << endl;
                    }
            }

            cout << "let's gry a group" <<endl;
            vit<int> g(v);
            int i;
            while(g.next(i)) { cout << i << endl; }

            cout << "now let's get really fancy" << endl;
            vit<int> a_vit(v);
            //auto is_same = [](int a, int b) { return a == b; };
            a_vit.set_same(is_same);
            //int total;
            while(a_vit.next(i)) {
                    if(a_vit.grp_begin()) total = 0;
                    total += i;
                    if(a_vit.grp_end()) cout << total << endl ;
            }
    }        

当我使用g ++ -std = c ++ 11 iter.cc -o iter编译它时,我得到了结果:

    iter.cc: In function 'int main()':
    iter.cc:63:17: error: reference to 'is_same' is ambiguous
      a_vit.set_same(is_same);
             ^
    iter.cc:37:6: note: candidates are: bool is_same(int, int)
     bool is_same(int a, int b) { return a == b; }
          ^
    In file included from /usr/include/c++/5.3.0/bits/move.h:57:0,
                     from /usr/include/c++/5.3.0/bits/stl_pair.h:59,
                     from /usr/include/c++/5.3.0/utility:70,
                     from /usr/include/c++/5.3.0/tuple:38,
                     from /usr/include/c++/5.3.0/functional:55,
                     from iter.cc:1:
    /usr/include/c++/5.3.0/type_traits:958:12: note:                         template<class, class> struct std::is_same
         struct is_same;
                ^

作为解释,我创建了一个名为'vit'的类。它做了两件事:迭代向量,并确定是否已到达新组。

类函数'set_same'应该存储由调用类提供的函数,以确定向量的两个相邻元素是否在同一个组中。但是,由于is_same的表面歧义,我似乎无法将该函数存储在类中以供将来使用grp_begin()和grp_end()。

是什么给出了?

3 个答案:

答案 0 :(得分:5)

您定义了is_same函数,并且定义了is_same结构by the C++ Standard Library。由于您是using namespace std,因此您的编译器并不知道您打算使用哪个is_same

答案 1 :(得分:3)

错误说明了什么:不清楚您是否您的 is_same(在全局命名空间中)或the class template is_same (in namespace std) <。 / p>

您可以按照以下方式消除歧义:

::is_same

...在全局命名空间中使用前导::含义&#34;&#34;。

虽然您应该考虑将代码放在自己的命名空间中。

答案 2 :(得分:1)

谢谢你们。这是我十多年来第一次接触C ++。我已经清理了代码,并使用lambda来带来&#34; is_same&#34;功能更接近它的所在地。

您是否发现了我的代码中的错误? &#39; POS&#39;在调用grp_begin()和grp_end()时,它是一个接一个的。以下是修订后的代码:

    #include <functional>
    #include <iostream>
    #include <vector>


    // vector iterator
    template <class T> class vit
    {
            private:
                    std::vector<T> m_v;
                    std::function<bool (T, T)> m_fptr;
                    int len, pos;
            public:
                    vit(std::vector<T> &v) { m_v = v; len = v.size();         pos = -1;};
                    bool next(T &val) {
                            pos++;
                            if(pos==len) return false;
                            val = m_v[pos];
                            return true;};
                    void set_same(std::function<bool (T,T)> fptr)         {         m_fptr = fptr ;};
                    bool grp_begin() {
                            return pos == 0 || ! m_fptr(m_v[pos],         m_v[pos-1]); };
                    bool grp_end() {
                            return pos+1 == len || ! m_fptr(m_v[pos], m_v[pos+1]); };
    };





    main()
    {
            std::vector<int>  v ={ 1, 1, 2, 2, 2, 3, 1, 1, 1 };
            vit<int> a_vit(v);
            std::function<bool (int, int)> is_same = [](int a, int b) { return a == b; };
            a_vit.set_same(is_same);
            int i, total;
            while(a_vit.next(i)) {
                    if(a_vit.grp_begin()) total = 0;
                    total += i;
                    if(a_vit.grp_end()) std::cout << total << std::endl ;
            }
    }

我的班级定义不具备防弹功能,可能会更好:例如,如果用户忘记设置相同的内容,他们就会将随机内存地址称为一个功能。

然而,到目前为止,我对我的解决方案非常满意。类调用者可以解除与向量迭代相关的所有簿记,并在组合边界已经越过时进行计算。

调用代码看起来非常紧凑和直观。我可以看到C ++是我的语言。