C++ 在const memeber函数中使用bind1st ClassA&operator

C++ 在const memeber函数中使用bind1st ClassA&operator,c++,linux,stl,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&l

您将错误的类型传递到了
二进制函数中

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
下面是一个小得多的例子:

struct  InsertOpt : binary_function<ClassA&, int, ClassA&>
{
    // rest as before
};
struct InsertOpt:
二进制函数
//^^^如果将其更改为int&,它将编译
{
int&operator()(int&a,int-b)常量{
标准::cout
通常,传递给一元函数或
二进制函数具有剥离的常量和引用。”

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

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));
}
  • 构造函数使用
    x
    初始化
    op
    ,使用
    y
    初始化值

  • operator()
    返回
    op(值,x)

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

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

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


    .

    这不应该是
    二进制函数吗?
    ?在有效的STL中,第40项。使函子类具有适应性,“一般来说,传递给一元函数或二进制函数的非指针类型会去掉常量和引用。”这可能是不正确的,也可能是您误解了它。没有什么魔法可以让您仅仅因为将常量对象传递给函子而将其作为非常量引用参数传递。此外,我应该补充一点,您似乎正在使用g++4.1,这在这一点上相当旧。我会尝试使用较新的g++。@cdhowie,是的,我使用的是old编译器,由于工作原因,我必须坚持使用它。谢谢。没有。我传递了正确的一个。请参考我上面的评论。即使在进行此更改时,编译器也会生成相同的错误消息。@q0987没有,您没有。您必须在那里指定
    类和
    。如果在添加
    后仍然出现错误,则它是a分离问题。
    &
    为我修复了它。谢谢你的示例。我认为问题来自我的旧编译器。
    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));
    }
    
    template <class Arg1, class Arg2, class Result>
    struct binary_function
    {
        typedef Arg1 first_argument_type;
        typedef Arg2 second_argument_type;
        typedef Result result_type;
    };
    
    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;
    };