使用not2时,struct vs class作为STL仿函数

时间:2009-12-08 21:40:01

标签: c++ class stl struct

Studing STL我写了一个简单的程序来测试仿函数和修饰符。我的问题是关于使用CLASS或STRUCT编写仿函数并尝试使用函数适配器对其进行操作的差异。 据我所知,在C ++中,CLASS和STRUCT之间的区别在于,在最后一种情况下,成员默认是公共的。这也是我在本网站的答案中多次阅读的内容。所以请解释一下,为什么这段短代码无法编译,即使我在尝试使用not2修饰符时声明所有成员(只是函数重载())公开。 (我还没有尝试过其他修饰符,例如粘合剂)

#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:
  在实例化   'std :: binary_negate&gt;':
  struct.cpp:52:从中实例化   这里
  /usr/include/c++/4.2.1/bits/stl_function.h:116:
  错误:'typedef int   std :: binary_function :: first_argument_type'是   人迹罕至
  /usr/include/c++/4.2.1/bits/stl_function.h:338:
  错误:在此背景下   /usr/include/c++/4.2.1/bits/stl_function.h:119:
  错误:'typedef int   std :: binary_function :: second_argument_type'是   无法进入......

似乎至少在这种情况下,结构不等同于具有公共成员的类,但为什么呢?

2 个答案:

答案 0 :(得分:11)

您从其他答案中读取的差异是正确的。默认情况下,struct只是classpublic可访问性。这包括继承修饰符。基本上,当您使用public来使这些定义等效时,您应该在基类名称之前提及class

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的定义,并看到编译器发出类似错误消息的声音。

答案 1 :(得分:2)

对于结构,默认情况下继承是公共的,默认情况下它是私有的(如果你没有指定public / private / protected)

所以:

class mystruct : binary_function

装置

class mystruct : private binary_function

struct mystruct : binary_function

装置

struct mystruct : public binary_function

对于私人继承,mystruct可以使用binary_function中的所有公开内容,但您无法在binary_functionmystruct上调用mystruct的公开方法不属于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
};