2009-12-08 44 views
3

Studing STL我已經編寫了一個簡單的程序來測試仿函數和修飾符。我的問題是關於使用CLASS或STRUCT編寫仿函數並試圖用函數適配器對其進行操作的區別。 據我瞭解,在C++中,CLASS和STRUCT之間的區別在於,在最後一種情況下,成員默認是公開的。這也是我在本網站的答案中多次閱讀的內容。因此,請解釋爲什麼即使我嘗試使用not2修飾符時聲明所有成員(只是函數overloading())public,這段代碼仍然無法編譯。 (我還沒有嘗試過其他改性劑如粘合劑還)使用not2時struct和class爲STL仿函數

#include <iostream> 
#include <vector> 
#include <functional> 
#include <algorithm> 
using namespace std; 

template <class T> 
void print (T i) { 
    cout << " " << i; 
} 
// In the manual I read: 
// "In C++, a structure is the same as a class except that its members are public by default." 
// So if I declare all members public it should work.... 

template <class T> 
class mystruct : binary_function<T ,T ,bool> { 
    public : 
    bool operator() (T i,T j) const { return i<j; } 
}; 

template <class T> 
class generatore 
{ 
public: 
    generatore (T start = 0, T stp = 1) : current(start), step(stp) 
    { } 
    T operator()() { return current+=step; } 
private: 
    T current; 
    T step; 
}; 

int main() { 
    vector<int> first(10); 
    generate(first.begin(), first.end(), generatore<int>(10,10)); 
    first.resize(first.size()*2); 
    generate(first.begin()+first.size()/2, first.end(), generatore<int>(1,17)); 
    cout << "\nfirst :"; 
    for_each (first.begin(), first.end(), print<int>); 
    cout << "\nFORWARD SORT :"; 
    sort(first.begin(),first.end(),mystruct<int>());  // OK ! even with CLASS 
    for_each (first.begin(), first.end(), print<int>); 
    sort(first.begin(),first.end(),not2(mystruct<int>())); // <--- THIS LINE WILL NOT COMPILE IF I USE CLASS INSTEAD OF STRUCT 
    cout << "\nBACKWARD SORT :"; 
    for_each (first.begin(), first.end(), print<int>); 
    cout << endl; 
} 

Everithing運行,如果我使用預期:

錯誤消息我得到的
struct mystruct : binary_function<T ,T ,bool> { 
    public : 
    bool operator() (T i,T j) const { return i<j; } 
}; 

部分是:

g++ struct.cpp
/usr/include/c++/4.2.1/bits/stl_function.h:
In instantiation of ‘std::binary_negate >’:
struct.cpp:52: instantiated from here
/usr/include/c++/4.2.1/bits/stl_function.h:116:
error: ‘typedef int std::binary_function::first_argument_type’ is inaccessible
/usr/include/c++/4.2.1/bits/stl_function.h:338:
error: within this context
/usr/include/c++/4.2.1/bits/stl_function.h:119:
error: ‘typedef int std::binary_function::second_argument_type’ is inaccessible ....

似乎至少在這種情況下,一個結構體不等同於有公共成員的類,但爲什麼?

回答

10

您從其他答案讀取的區別是正確的。 struct只是一個class默認情況下爲public輔助功能。這包括繼承修飾符。基本上,你應該當你使用一個class,使這些定義相當於提public基類名前:

template <class T> 
class mystruct : public binary_function<T ,T ,bool> { 
    public: 
    bool operator() (T i,T j) const { return i<j; } 
}; 

否則,編譯器將假定mystruct是私有繼承binary_function<T,T,bool>

您可以通過更改驗證這個事實struct到:

struct mystruct : private binary_function<T ,T ,bool> { 
    public: // not required here 
    bool operator() (T i,T j) const { return i<j; } 
}; 

這相當於你當前的class的定義,並看到類似的錯誤消息編譯器的哀鳴。

+0

好!現在工作。 !謝謝 ! – GBBL 2009-12-08 21:52:30

2

隨着結構的繼承是公共默認與類它是私有的默認情況下(如果不指定公共/私有/保護)

所以:

class mystruct : binary_function

意味着

class mystruct : private binary_function

但是

struct mystruct : binary_function

意味着

struct mystruct : public binary_function

對於私有繼承mystruct可以使用所有的公共的東西從binary_function但你不能調用binary_function公共方法上mystructmystruct不是binary_function類型(我相信)。

因此,當您將mystruct傳遞到預期的binary_function時,mystruct未定義從binary_function預期的東西。

更具體地說,仿函數預計將有由binary_function提供的如下定義,所以當你從它繼承你已經有了這些聲明:

template <class _Arg1, class _Arg2, class _Result> 
struct binary_function { 
    typedef _Arg1 first_argument_type; ///< the type of the first argument (no surprises here) 
    typedef _Arg2 second_argument_type; ///< the type of the second argument 
    typedef _Result result_type;   ///< type of the return type 
};