2014-11-21 48 views
2
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使用bind1st在常量memeber功能

謝謝

+0

不應該是'binary_function '? – cdhowie 2014-11-21 17:31:05

+0

In effective STL,Item 40. Make functor classes adaptable,「一般來說,傳遞給unary_function或binary_function的非指針類型會刪除const和引用。」 – q0987 2014-11-21 17:34:32

+0

要麼是不正確的,要麼是你誤解了它。僅僅因爲你將它傳遞給一個仿函數,沒有魔法允許你將const對象作爲非const引用參數傳遞。 – cdhowie 2014-11-21 17:43:05

回答

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)); 
} 
+0

不,我通過了正確的。請參考我上面的評論。即使發生這種變化,編譯器也會生成相同的錯誤消息。 – q0987 2014-11-21 17:35:50

+0

@ q0987不,你沒有。你必須指定'Class&'那裏。如果在添加'&'後仍然出現錯誤,那麼這是一個單獨的問題。 '&'爲我修復它。 – Barry 2014-11-21 17:45:30

+0

謝謝你的例子。我認爲問題來自我的舊版編譯器。 – q0987 2014-11-21 18:01:07

1

「在通過一般情況下,非指針類型unary_function或 binary_function有consts和引用剝離。」

這是不正確的。這意味着某些衰減適用於binary_function的模板參數(例如,通過std::decay)。但標準定義binary_function相當明確地在[depr.base]:

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. 構造使用x初始化op,值爲y

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

正如可以看到的參數所存儲的功能目的是value,這是typename Fn::first_argument_type類型。 但是請注意operator()裏面是怎麼標記const的。成員valueconst對象的形式傳遞,因此InsertOpt僅接受非const左值作爲第一個參數,從而導致出現錯誤消息。

然而,當第一個參數類型被給定爲一個左值參考,通過const訪問路徑訪問value時,將所得的value類型是「左值參照非const ClassA」參考塌陷規則適用。

即使發生此更改,編譯器也會生成相同的錯誤消息。

Compiles for me