重写专门女儿中的模板函数 class
Overriding template function in specialized daughter class
我有一个模板化的 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;
}
我知道有一个女儿class 模板专用的匹配。用于专业化的 class Place
没有 operator==
来进行比较。因此,我试图覆盖 operator==
以使用 class 地方。
关于我尝试过的事情:
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 class.
编译方法
我有什么办法可以覆盖女儿 class 中基 class 的这个功能吗?我已经阅读了问题 here 但这里是专门的方法,而我的 class 是专门的,所以我不知道如何进行前向声明:/.
该函数可能是虚函数,但在您继承基函数时它仍会被初始化 class。
这很重要,因为您可能会这样写:
MatchBase<Place> test = Match(p1,p2);
MatchBase<Place>
是 Match
的基础 class 但它们并不相同。
调用 MatchBase<Place>::operator==()
仍将调用模板库中定义的函数 class.
您现在有多种选择:
- 使基 class 中的函数成为纯虚函数
- 实施 Place::operator==()
- 将一个比较器作为参数传递给你的基础 class 作为参数
前两个应该清楚(如果不清楚请询问)。对于第三种,这可能是一种可行的方法:
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
模板参数。
如果您不打算使用预定义类型(考虑 int
、std::string
等...),您还可以确保 class 作为 Element
必须继承 class/struct 强制实施 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)
{};
};
我有一个模板化的 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;
}
我知道有一个女儿class 模板专用的匹配。用于专业化的 class Place
没有 operator==
来进行比较。因此,我试图覆盖 operator==
以使用 class 地方。
关于我尝试过的事情:
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 class.
编译方法我有什么办法可以覆盖女儿 class 中基 class 的这个功能吗?我已经阅读了问题 here 但这里是专门的方法,而我的 class 是专门的,所以我不知道如何进行前向声明:/.
该函数可能是虚函数,但在您继承基函数时它仍会被初始化 class。 这很重要,因为您可能会这样写:
MatchBase<Place> test = Match(p1,p2);
MatchBase<Place>
是 Match
的基础 class 但它们并不相同。
调用 MatchBase<Place>::operator==()
仍将调用模板库中定义的函数 class.
您现在有多种选择:
- 使基 class 中的函数成为纯虚函数
- 实施 Place::operator==()
- 将一个比较器作为参数传递给你的基础 class 作为参数
前两个应该清楚(如果不清楚请询问)。对于第三种,这可能是一种可行的方法:
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
模板参数。
如果您不打算使用预定义类型(考虑 int
、std::string
等...),您还可以确保 class 作为 Element
必须继承 class/struct 强制实施 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)
{};
};