在const成员函数中使用bind1st

时间:2014-11-21 17:28:06

标签: c++ linux stl

ClassA & operator << ( ClassA &, int32_t )
{
    ...
}


class ClassMain
{
public:
    insert( ClassA & c ) const;
    ...
private:
    std::set<int> m_setContainer;
};

struct  InsertOpt : binary_function<ClassA, int, ClassA&>
{
        ClassA & operator( )( ClassA & c, int val ) const
        {
                c << val;
                return c;
        }
};

void ClassMain::insert( ClassA & c ) const
{
    // Case I: the for loop works
    for ( std::set<int>::const_iterator iter = m_setContainer.begin( );
          iter != m_setContainer.end( ); ++iter )
    {
            c << *iter; // operator<<( c, *iter );
    }

    // Case II: doesn't work
    for_each( m_setContainer.begin( ), m_setContainer.end( ), bind1st( InsertOpt(), c ) );


}

Error:
../include/c++/4.1.2/bits/stl_function.h:406: error: no match for call to '(const InsertOpt) (const ClassA&, const int&)'
note: candidates are: ClassA& InsertOpt::operator()(ClassA&, int32_t) const

问题&GT;为什么编译器会查找(const ClassA&, const int&)而不是ClassA & operator( )( ClassA & c, int val ) const

谢谢

2 个答案:

答案 0 :(得分:1)

  

“通常,非指针类型传递给unary_function或   binary_function已经删除了consts和references。“

这是不正确的。这意味着某些衰减应用于binary_function的模板参数(例如,通过std::decay)。但是标准在[depr.base]中非常明确地定义了binary_function

template <class Arg1, class Arg2, class Result>
struct binary_function
{
    typedef Arg1 first_argument_type;
    typedef Arg2 second_argument_type;
    typedef Result result_type;
};

binder1st在[depr.lib.binder.1st]中定义:

template <class Fn>
class binder1st : public unary_function<typename Fn::second_argument_type,
                                        typename Fn::result_type>
{
protected:
    Fn op;
    typename Fn::first_argument_type value;

public:
    binder1st(const Fn& x,
              const typename Fn::first_argument_type& y);

    typename Fn::result_type
    operator()(const typename Fn::second_argument_type& x) const;
    typename Fn::result_type
    operator()(typename Fn::second_argument_type& x) const;
};
     
      
  1. 构造函数使用op初始化x,使用y初始化值。

  2.   
  3. operator()返回op(value,x)

  4.   

正如您所看到的,存储函数对象的参数是value,其类型为typename Fn::first_argument_type但请注意operator()内部标记为const的方式。成员value作为const对象传递,这会导致您的错误消息,因为InsertOpt仅接受非const左值作为第一个参数。

但是,当第一个参数类型作为左值引用给出时,引用折叠规则在通过value访问路径访问const时适用,结果类型value为“左值”引用非const ClassA“。

  

即使进行此更改,编译器也会生成相同的错误消息。

Compiles for me

答案 1 :(得分:0)

您将错误的类型传递给binary_function

struct  InsertOpt : binary_function<ClassA, int, ClassA&>
 //                                 ^^^^^^
{
        ClassA & operator( )( ClassA & c, int val ) const
        {
                c << val;
                return c;
        }
};

您的operator()需要ClassA&,但您说它需要ClassA。那些需要排队:

struct  InsertOpt : binary_function<ClassA&, int, ClassA&>
{
    // rest as before
};

这是一个小得多的例子:

struct InsertOpt :
    std::binary_function<int, int, int&>
    //                   ^^^ if you change this to int&, it compiles
{
    int& operator()(int& a, int b) const {
        std::cout << b << std::endl;
        return a;
    }
};

int main() {
    const std::vector<int> v = {1, 2, 3, 4};
    int a = 5;

    std::for_each(v.begin(), v.end(), std::bind1st(InsertOpt(), a));
}