Studing STL I have written a a simple program to test functors and modifiers. My question is about the difference aon using CLASS or STRUCT to write a functor and try to operate on it with function adaptors. As far as I understand in C++ the difference beetween CLASS and STRUCT is that in the last case the members are public by default. This is also what I read many times in the answers in this site. So please explain m开发者_StackOverflow社区e why this short piece of code will fail to compile even if I declared all members ( just a function overloading () ) public when I try to use the not2 modifier. (I have not tried other modifiers e.g. binders yet)
#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 runs as expected if I use:
struct mystruct : binary_function<T ,T ,bool> {
public :
bool operator() (T i,T j) const { return i<j; }
};
Part of the error message I obtain is:
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 ....
Seems that at least in this case a struct is not equivalent to a class with public members, but why ?
The difference you read from other answers is correct. struct
is just a class
with public
accessibility by default. This includes the inheritance modifier. Basically, you should mention public
before the base class name when you're using a class
to make those definitions equivalent:
template <class T>
class mystruct : public binary_function<T ,T ,bool> {
public:
bool operator() (T i,T j) const { return i<j; }
};
Otherwise, the compiler will assume that mystruct
is privately inheriting binary_function<T,T,bool>
.
You can verify this fact by changing the struct
to:
struct mystruct : private binary_function<T ,T ,bool> {
public: // not required here
bool operator() (T i,T j) const { return i<j; }
};
which is equivalent to your current definition of the class
and see the compiler whine with a similar error message.
With structure the inheritance is public by default with class it's private by default (if you don't specify public/private/protected)
So:
class mystruct : binary_function
means
class mystruct : private binary_function
but
struct mystruct : binary_function
means
struct mystruct : public binary_function
For private inheritance the mystruct
can use all the public stuff from binary_function
but you can't call public method of binary_function
on mystruct
and mystruct
is not of binary_function
type (I believe).
So when you pass mystruct
to where binary_function
is expected, mystruct
does not define stuff that is expected from binary_function
.
More specifically, the functor is expected to have the following definitions that are provided by binary_function
, so when you inherit from it you already have those declarations:
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
};
精彩评论