std :: set使用派生类对象,但基类比较器使用gcc8.1

时间:2018-07-17 19:35:25

标签: c++ c++17 gcc8

a.h

#ifndef _A__
#define _A__
class A {
  public:
    struct Less {
      bool operator() (const A* const &k1, const A* const &k2) const
      {
        return k1->_a < k2->_a;
      }
    };
    A(int a) : _a(a)
  {
    ;
  }
    virtual ~A()
    {
      ;
    }
  private:
    int _a;
};

#endif

b.h

#ifndef _B__
#define _B__
#include "a.h"

class B : public A {
  public:
    B(int a) : A(a)
  {
    ;
  }
    ~B()
    {
      ;
    }
};

#endif // _B__

c.cpp

#include <set>
#include "a.h"
class B;
class C
{
  std::set<B*, A::Less> _set;
};

使用g ++ 8.1编译c.cpp时,无法通过此静态检查错误进行编译

/export/dev6/rajpal/gcc/8.1.0/bin/g++ -c c.cpp
In file included from /export/dev6/rajpal/gcc/8.1.0/include/c++/8.1.0/set:60,
                 from c.cpp:1:
/export/dev6/rajpal/gcc/8.1.0/include/c++/8.1.0/bits/stl_tree.h: In instantiation of 'class std::_Rb_tree<B*, B*, std::_Identity<B*>, A::Less, std::allocator<B*> >':
/export/dev6/rajpal/gcc/8.1.0/include/c++/8.1.0/bits/stl_set.h:133:17:   required from 'class std::set<B*, A::Less>'
c.cpp:6:25:   required from here
/export/dev6/rajpal/gcc/8.1.0/include/c++/8.1.0/bits/stl_tree.h:452:21: error: static assertion failed: comparison object must be invocable with two arguments of key type
       static_assert(__is_invocable<_Compare&, const _Key&, const _Key&>{},
                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我理解错误是因为在编译时,编译器无法确定如何比较_Key=B*,并且如果我提供B的定义,它应该可以正常工作。

但是,我的问题是,是否有任何方法可以告诉编译器B实际上是从A派生的,并且有一种方法可以比较A对象。

还请注意,我不想将std::set<B*, A::Less>更改为std::set<A*, A::Less>,这也可以解决此问题。

2 个答案:

答案 0 :(得分:1)

  

但是,我的问题是,是否有任何方法可以告诉编译器A实际上是从B派生的

唯一的方法是在需要该信息的地方显示B的定义。

没有什么比类的前向声明更能表明A源自actCashDwnAmt了。

答案 1 :(得分:1)

好吧,这实际上是一个libstdc ++错误,将在GCC 8.4中修复: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85965