繁体   English   中英

专门的子类中的重写模板功能

[英]Overriding template function in specialized daughter class

我有一个模板类MatchBase,它具有运算符==这样的函数

template<typename Element>
class MatchBase{
    virtual bool operator ==(const MatchBase<Element>& m) const{
    if(_v1 == m.getFirst() && _v2 == m.getSecond()){
        return true;
    }
    return false;
}

我知道有一个专门针对模板的子类Match。 用于专业化的Place类没有operator==进行比较。 因此,我试图覆盖operator==以使用Place类。

在我尝试过的事情上:

class Match : public betterGraph::MatchBase<graphmatch::Place>{
public :
    Match(const graphmatch::Place& v, const graphmatch::Place& vv) : 
        betterGraph::MatchBase<graphmatch::Place>(v, vv) 
        {};

    virtual bool operator ==(const Match& m) const{
        if(_v1.mass_center == m.getFirst().mass_center && _v2.mass_center == m.getSecond().mass_center){
            return true;
        }
        return false;
    }

};

我也试过

virtual bool operator ==(const betterGraph::MatchBase<graphmatch::Place>& m) const{
    if(_v1.mass_center == m.getFirst().mass_center && _v2.mass_center == m.getSecond().mass_center){
        return true;
    }
    return false;
}

但是我总是遇到以下类型的错误:

error: no match for ‘operator==’ (operand types are ‘const AASS::graphmatch::Place’ and ‘const AASS::graphmatch::Place’)
if(_v1 == m.getFirst() && _v2 == m.getSecond()){

因为它尝试从Base类编译该方法。

我有什么办法可以在子类中重写基类的此功能? 我在这里阅读了问题但是在我的班级是专业的时候,这是专门的方法,所以我看不到如何做正向声明:/。

该函数可能是虚拟的,但在继承基类时仍会初始化。 这很重要,因为您可能会编写如下内容:

MatchBase<Place> test = Match(p1,p2);

MatchBase<Place>Match的基类,但它们并不相同。 调用MatchBase<Place>::operator==()仍将调用模板基类中定义的函数。

您现在有多个选择:-将基类中的函数设为纯虚函数-实现Place::operator==() -将编译器作为参数传递给您的基类作为参数

前两个应该清楚(如果没有请询问)。 对于第三种方法,这可能是一种可行的方法:

template<typename Element, typename Less = std::less<Element>>
class MatchBase {

protected:
    Element _v1;
    Element _v2;

public:
    MatchBase(const Element& v, const Element& vv) : _v1(v), _v2(vv)
    {}

    virtual bool operator ==(const MatchBase<Element, Less>& m) const {
        Less less;
        bool v1Equal = !less(_v1, m.getFirst()) && !less(m.getFirst(), _v1);
        bool v2Equal = !less(_v2, m.getSecond()) && !less(m.getSecond(), _v2);
        return v1Equal && v2Equal;
    }

    const Element& getFirst() const { return _v1; }
    const Element& getSecond() const { return _v2; }

};

struct Place
{
    int mass_center;
};

struct PlaceLess
{
    bool operator()(const Place& p1, const Place& p2) 
    {
        return p1.mass_center < p2.mass_center; 
    };
};

class Match : public MatchBase <Place, PlaceLess>
{
public:
    Match(const Place& v, const Place& vv) :
        MatchBase<Place, PlaceLess>(v, vv)
    {};
};

另一种方法可能是在这种情况下专门化std::less<T> 因此,您无需将其作为模板参数传递。

template<typename Element>
class MatchBase {

protected:
    Element _v1;
    Element _v2;

public:
    MatchBase(const Element& v, const Element& vv) : _v1(v), _v2(vv)
    {}

    virtual bool operator ==(const MatchBase<Element>& m) const {
        std::less<Element> less;
        bool v1Equal = !less(_v1, m.getFirst()) && !less(m.getFirst(), _v1);
        bool v2Equal = !less(_v2, m.getSecond()) && !less(m.getSecond(), _v2);
        return v1Equal && v2Equal;
    }

    const Element& getFirst() const { return _v1; }
    const Element& getSecond() const { return _v2; }

};

struct Place
{
    int mass_center;
};

template<>
struct std::less<Place>
{
    bool operator()(const Place& p1, const Place& p2) 
    {
        return p1.mass_center < p2.mass_center; 
    };
};

class Match : public MatchBase <Place>
{
public:
    Match(const Place& v, const Place& vv) :
        MatchBase<Place>(v, vv)
    {};
};

当然,您可以合并这些方式,以便在需要时可以覆盖Less模板参数。

如果您不打算使用预定义的类型(例如intstd::string等的思考),则还可以确保以Element传递的类必须继承一个强制执行operator==的类/结构。 :

template <typename T>
struct IComparable
{
    virtual bool operator==(const T& other) const = 0;
};


template<typename Element>
class MatchBase {

    static_assert(std::is_base_of<IComparable<Element>, Element>::value, "Element must implement comparable");

protected:
    Element _v1;
    Element _v2;

public:
    MatchBase(const Element& v, const Element& vv) : _v1(v), _v2(vv)
    {}

    virtual bool operator ==(const MatchBase<Element>& m) const {
        return _v1 == m._v1 && _v2 == m._v2;
    }
};

struct Place : public IComparable<Place>
{
    int mass_center;

    bool operator==(const Place& other) const
    {
        return mass_center == other.mass_center;
    };
};

class Match : public MatchBase <Place>
{
public:
    Match(const Place& v, const Place& vv) :
        MatchBase<Place>(v, vv)
    {};
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM