boost::bind 到 std::lower_bound 有效,但 C++0x std::bind 无法编译

发布于 2024-11-24 08:00:13 字数 9078 浏览 0 评论 0原文

我正在为符合 STL 算法的 zip 迭代器进行概念验证。 const 正确性是不完整的,它肯定可以做得更好,但它适用于 std::for_each、std::upper_bound 和 std::lower_bound。直到我用 tr1::bind 替换它。那时我无法编译并出现许多模板错误。我已经包含了下面的代码,但我不知道如何追踪它。任何帮助表示赞赏。

容器类

#pragma once

#include <vector>

class Container
{
public:
    class ZippedInfo
    {
    public:
        ZippedInfo(int& pos, Container* cont):
            m_pos(pos), 
            m_cont(cont)
            {};

        double& Bar(){ return m_cont->Bar(m_pos);}

        double& Foo(){ return m_cont->Foo(m_pos);}
    private:
        int& m_pos;
        Container* m_cont;
    };

    class iterator : public std::iterator<std::random_access_iterator_tag, ZippedInfo> 
    {
    public:
        iterator(int pos, Container* cont):
          m_Pos(pos), 
          m_Container(cont),
          m_ZippedInfo(m_Pos, cont)
          {}

          iterator():
              m_Pos(0), 
              m_Container(nullptr),
              m_ZippedInfo(m_Pos, nullptr)
          {}


        iterator(const iterator& rhs):
          m_Pos(rhs.m_Pos),
          m_Container(rhs.m_Container),
          m_ZippedInfo(m_Pos, rhs.m_Container)
        {}  

        ZippedInfo& operator*() {return m_ZippedInfo;}

        iterator& operator=(const iterator& rhs)
        {
            m_Container = rhs.m_Container;
            m_Pos = rhs.m_Pos;
            return *this;
        }

        iterator& operator += (int increment)
        {
            m_Pos += increment;
            return *this;
        }

        bool operator !=(const iterator& rhs)
        {
            return !(operator==(rhs));
        }

        bool operator ==(const iterator& rhs)
        {
            return m_Container == rhs.m_Container && m_Pos == rhs.m_Pos;
        }

        iterator& operator++()
        {
            m_Pos++;
            return *this;
        }

        int operator -(const iterator& rhs)
        {
            return m_Pos - rhs.m_Pos;
        }

        bool operator < (const iterator& rhs)
        {
            return m_Pos < rhs.m_Pos;
        }
    private:
        int m_Pos;
        ZippedInfo m_ZippedInfo;
        Container* m_Container;
    };

    Container() {}
    Container(const std::vector<double> &bar, const std::vector<double>& foo):
        m_bar(bar),
        m_foo(foo)
    {   }


    iterator begin()
    {
        return iterator(0, this);
    }

    iterator end()
    {
        return iterator(m_foo.size(), this);
    }

    double& Foo(int index){return m_foo[index];}
    double& Bar(int index){return m_bar[index];}
private:
    std::vector<double> m_foo;
    std::vector<double> m_bar;
};

主程序

#include "stdafx.h"
#include <algorithm>
#include <iostream>
#include <string>
#include <functional>
#include <boost\bind.hpp>
#include "test_iter.h"

using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
    vector<double> foo;
    foo.push_back(1);
    foo.push_back(2);
    foo.push_back(3);
    foo.push_back(4);
    foo.push_back(5);

    vector<double>bar;
    bar.push_back(1);
    bar.push_back(3);
    bar.push_back(5);
    bar.push_back(7);
    bar.push_back(9);

    Container c(bar, foo);

    double searchnum = 3;


    /*Container::iterator cf_iter3 = std::lower_bound(c.begin(), 
                                        c.end(), 
                                        searchnum,
                                        std::tr1::bind(&Container::ZippedInfo::Bar, std::tr1::placeholders::_1) < searchnum );*/

    Container::iterator cf_iter2 = std::lower_bound(c.begin(), 
                                        c.end(), 
                                        searchnum,
                                        boost::bind(&Container::ZippedInfo::Bar, _1) < searchnum );

    cout << (*cf_iter2).Bar() << endl;

boost版本可以工作,tr1版本给出以下错误

error C2065: 'cf_iter' : undeclared identifier
error C2228: left of '.Bar' must have class/struct/union
error C2676: binary '<' : 'std::tr1::_Bind<_Result_type,_Ret,_BindN>' does not define this operator or a conversion to a type acceptable to the predefined operator
error C2780: '_FwdIt std::lower_bound(_FwdIt,_FwdIt,const _Ty &)' : expects 3 arguments - 4 provided
error C2784: 'bool std::operator <(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const _Elem *' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::unique_ptr<_Ty,_Dx> &,const std::unique_ptr<_Ty2,_Dx2> &)' : could not deduce template argument for 'const std::unique_ptr<_Ty,_Dx> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::unique_ptr<_Ty,_Dx> &,const std::unique_ptr<_Ty2,_Dx2> &)' : could not deduce template argument for 'const std::unique_ptr<_Ty,_Dx> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::vector<_Ty,_Ax> &,const std::vector<_Ty,_Ax> &)' : could not deduce template argument for 'const std::vector<_Ty,_Ax> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::vector<_Ty,_Ax> &,const std::vector<_Ty,_Ax> &)' : could not deduce template argument for 'const std::vector<_Ty,_Ax> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::tr1::operator <(const std::tr1::shared_ptr<_Ty> &,const std::tr1::shared_ptr<_Ty2> &)' : could not deduce template argument for 'const std::tr1::shared_ptr<_Ty> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::tr1::operator <(const std::tr1::shared_ptr<_Ty> &,const std::tr1::shared_ptr<_Ty2> &)' : could not deduce template argument for 'const std::tr1::shared_ptr<_Ty> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'

I'm working on a proof of concept here for a zip iterator that conforms to STL algorithms. const correctness is incomplete and it could definitely be made much better, but it works for std::for_each, std::upper_bound and std::lower_bound. That is until I replace it with tr1::bind. At that point I fail to compile with numerous template errors. I've included the code below, but I have no idea how to trace this down. Any help is appreciated.

Container class

#pragma once

#include <vector>

class Container
{
public:
    class ZippedInfo
    {
    public:
        ZippedInfo(int& pos, Container* cont):
            m_pos(pos), 
            m_cont(cont)
            {};

        double& Bar(){ return m_cont->Bar(m_pos);}

        double& Foo(){ return m_cont->Foo(m_pos);}
    private:
        int& m_pos;
        Container* m_cont;
    };

    class iterator : public std::iterator<std::random_access_iterator_tag, ZippedInfo> 
    {
    public:
        iterator(int pos, Container* cont):
          m_Pos(pos), 
          m_Container(cont),
          m_ZippedInfo(m_Pos, cont)
          {}

          iterator():
              m_Pos(0), 
              m_Container(nullptr),
              m_ZippedInfo(m_Pos, nullptr)
          {}


        iterator(const iterator& rhs):
          m_Pos(rhs.m_Pos),
          m_Container(rhs.m_Container),
          m_ZippedInfo(m_Pos, rhs.m_Container)
        {}  

        ZippedInfo& operator*() {return m_ZippedInfo;}

        iterator& operator=(const iterator& rhs)
        {
            m_Container = rhs.m_Container;
            m_Pos = rhs.m_Pos;
            return *this;
        }

        iterator& operator += (int increment)
        {
            m_Pos += increment;
            return *this;
        }

        bool operator !=(const iterator& rhs)
        {
            return !(operator==(rhs));
        }

        bool operator ==(const iterator& rhs)
        {
            return m_Container == rhs.m_Container && m_Pos == rhs.m_Pos;
        }

        iterator& operator++()
        {
            m_Pos++;
            return *this;
        }

        int operator -(const iterator& rhs)
        {
            return m_Pos - rhs.m_Pos;
        }

        bool operator < (const iterator& rhs)
        {
            return m_Pos < rhs.m_Pos;
        }
    private:
        int m_Pos;
        ZippedInfo m_ZippedInfo;
        Container* m_Container;
    };

    Container() {}
    Container(const std::vector<double> &bar, const std::vector<double>& foo):
        m_bar(bar),
        m_foo(foo)
    {   }


    iterator begin()
    {
        return iterator(0, this);
    }

    iterator end()
    {
        return iterator(m_foo.size(), this);
    }

    double& Foo(int index){return m_foo[index];}
    double& Bar(int index){return m_bar[index];}
private:
    std::vector<double> m_foo;
    std::vector<double> m_bar;
};

Main program

#include "stdafx.h"
#include <algorithm>
#include <iostream>
#include <string>
#include <functional>
#include <boost\bind.hpp>
#include "test_iter.h"

using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
    vector<double> foo;
    foo.push_back(1);
    foo.push_back(2);
    foo.push_back(3);
    foo.push_back(4);
    foo.push_back(5);

    vector<double>bar;
    bar.push_back(1);
    bar.push_back(3);
    bar.push_back(5);
    bar.push_back(7);
    bar.push_back(9);

    Container c(bar, foo);

    double searchnum = 3;


    /*Container::iterator cf_iter3 = std::lower_bound(c.begin(), 
                                        c.end(), 
                                        searchnum,
                                        std::tr1::bind(&Container::ZippedInfo::Bar, std::tr1::placeholders::_1) < searchnum );*/

    Container::iterator cf_iter2 = std::lower_bound(c.begin(), 
                                        c.end(), 
                                        searchnum,
                                        boost::bind(&Container::ZippedInfo::Bar, _1) < searchnum );

    cout << (*cf_iter2).Bar() << endl;

The boost version works, the tr1 version gives the following errors

error C2065: 'cf_iter' : undeclared identifier
error C2228: left of '.Bar' must have class/struct/union
error C2676: binary '<' : 'std::tr1::_Bind<_Result_type,_Ret,_BindN>' does not define this operator or a conversion to a type acceptable to the predefined operator
error C2780: '_FwdIt std::lower_bound(_FwdIt,_FwdIt,const _Ty &)' : expects 3 arguments - 4 provided
error C2784: 'bool std::operator <(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const _Elem *' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::unique_ptr<_Ty,_Dx> &,const std::unique_ptr<_Ty2,_Dx2> &)' : could not deduce template argument for 'const std::unique_ptr<_Ty,_Dx> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::unique_ptr<_Ty,_Dx> &,const std::unique_ptr<_Ty2,_Dx2> &)' : could not deduce template argument for 'const std::unique_ptr<_Ty,_Dx> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::vector<_Ty,_Ax> &,const std::vector<_Ty,_Ax> &)' : could not deduce template argument for 'const std::vector<_Ty,_Ax> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::operator <(const std::vector<_Ty,_Ax> &,const std::vector<_Ty,_Ax> &)' : could not deduce template argument for 'const std::vector<_Ty,_Ax> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::tr1::operator <(const std::tr1::shared_ptr<_Ty> &,const std::tr1::shared_ptr<_Ty2> &)' : could not deduce template argument for 'const std::tr1::shared_ptr<_Ty> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'
error C2784: 'bool std::tr1::operator <(const std::tr1::shared_ptr<_Ty> &,const std::tr1::shared_ptr<_Ty2> &)' : could not deduce template argument for 'const std::tr1::shared_ptr<_Ty> &' from 'std::tr1::_Bind<_Result_type,_Ret,_BindN>'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

秋叶绚丽 2024-12-01 08:00:13

这里讨论的是C++0x,如果您愿意的话,可以对TR1进行适当的改编。

std::bindboost::bind 的不同之处在于它不为运算符提供便利的重载。使用文档,我们可以构建标准替代品:

Container::iterator cf_iter3 = std::lower_bound(c.begin(), c.end(), searchnum,
   std::bind(std::less<double>(),
             std::bind(&Container::ZippedInfo::Bar, std::placeholders::_1),
             searchnum)
                                               );

Talking about C++0x here, make the suitable adaptations for TR1 if you please.

std::bind differs from boost::bind in that it does not provide convenience overloads for operators. Using the documentation, we can build the standard replacement:

Container::iterator cf_iter3 = std::lower_bound(c.begin(), c.end(), searchnum,
   std::bind(std::less<double>(),
             std::bind(&Container::ZippedInfo::Bar, std::placeholders::_1),
             searchnum)
                                               );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文