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
问题>为什么编译器寻找(const ClassA&, const int&)
而不是ClassA & operator( )( ClassA & c, int val ) const
?
谢谢
“一般来说,传递给unary_function或binary_function的非指针类型的const和引用被剥离掉了。”
这是不正确的。 这意味着一些衰减被应用于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; };
构造函数用
x
初始化op
,用y
初始化value。
operator()
返回op(value,x)
。
正如你所看到的,存储函数对象的参数是一个value
,它的类型是typename Fn::first_argument_type
。 但是也要注意operator()
是如何在内部标记为const
。 成员value
作为一个const
对象传递 ,并导致您的错误消息,因为InsertOpt
只接受非常量InsertOpt
作为第一个参数。
但是,当第一个参数类型作为左值引用给出时,通过const
访问路径访问value
时引用合并规则适用,并且结果类型的value
“左值引用非常量ClassA
”。
即使发生这种更改,编译器也会生成相同的错误消息。
为我编译 。
您正在将错误的类型传递给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)); }