gpt4 book ai didi

C++ 关系运算符生成器

转载 作者:搜寻专家 更新时间:2023-10-31 00:35:41 25 4
gpt4 key购买 nike

一旦你定义了 <运算符,您可以估计其余关系运算符的行为方式。我正在尝试为我的类(class)实现一种方法。

我想要的是只定义 <其余的运算符将被隐式默认。到目前为止我得到的是这个设计,我将在下面详细说明:

template<typename T>
struct relational
{
friend bool operator> (T const &lhs, T const &rhs) { return rhs < lhs; }
friend bool operator==(T const &lhs, T const &rhs) { return !(lhs < rhs || lhs > rhs); }
friend bool operator!=(T const &lhs, T const &rhs) { return !(rhs == lhs); }
friend bool operator<=(T const &lhs, T const &rhs) { return !(rhs < lhs); }
friend bool operator>=(T const &lhs, T const &rhs) { return !(lhs < rhs); }
};

因此对于实现 < 的类运算符它只需要继承自 relational让其余的运营商违约。

struct foo : relational<foo>
{
// implement < operator here
};
  1. 是否有任何替代方案和更好的设计?
  2. 这段代码中有定时炸弹吗?我假设如果用户想要为其中一个运算符定义自定义实现,则重载解析将启动并选择非模板(用户定义)实现。如果不是这种情况(或者我会遇到从 relational 继承的类模板的问题),我应该在 relational 中实现运算符吗?像这样?

    // inside the relational struct
    friend bool operator>(relational const &lhs, relational const &rhs)
    { // functions that involve implicit conversion are less favourable in overload resolution
    return (T const&)rhs < (T const&)lhs;
    }

感谢您的建议,这里是demo of the code working

最佳答案

我通常使用从 Robert Martin 那里学到的技巧来做到这一点。我有一个模板类:

template <typename T>
class ComparisonOperators
{
protected:
~ComparisonOperators() {}

public:
friend bool operator==( T const& lhs, T const& rhs )
{
return lhs.compare( rhs ) == 0;
}
friend bool operator!=( T const& lhs, T const& rhs )
{
return lhs.compare( rhs ) != 0;
}
friend bool operator<( T const& lhs, T const& rhs )
{
return lhs.compare( rhs ) < 0;
}
friend bool operator<=( T const& lhs, T const& rhs )
{
return lhs.compare( rhs ) <= 0;
}
friend bool operator>( T const& lhs, T const& rhs )
{
return lhs.compare( rhs ) > 0;
}
friend bool operator>=( T const& lhs, T const& rhs )
{
return lhs.compare( rhs ) >= 0;
}
};

需要运算符的类派生自:

class Toto : public ComparisonOperators<Toto>
{
// ...
public:
// returns value < 0, == 0 or >0, according to
// whether this is <, == or > other.
int compare( Toto const& other ) const;
};

(我的实现其实有点复杂,因为它使用一些简单的元编程来调用 isEqual , 而不是 compare ,如果该函数存在。)

编辑:

然后重读您的问题:这基本上就是您正在做的事情,而且它几乎是此类事情的标准习语。我更喜欢使用命名函数,如 compare ,但这只是个人喜好。处理 isEqual 的元编程技巧, 然而,这是值得的:这意味着您可以对仅支持相等的类型使用相同的类;当编译器尝试实例化例如,你会得到一个错误operator<= ,但除非有人使用它,否则编译器不会尝试实例化它。通常情况是 isEqual可以比 compare 更有效地实现.

编辑 2:

它的值(value):我系统地这样做。我也有 ArithmeticOperators (根据 + 定义例如 +=), MixedTypeArithmeticOperators (和上面一样,但是有两个类型,T1 ,它是一个基类,T2 ;它提供所有运算符的组合)。和 STLIteratorOperators , 它实现了 STL 迭代器基于更合理和更容易的东西的界面实现(基本上,带有 isEqual 的 GoF 迭代器)功能)。他们节省了大量的样板文件。

编辑 3:

最后:我只是查看了工具包中的实际代码。有条件支持isEqual甚至比我想起来了:上面的模板类有一个公共(public)成员:

bool isEqual( T const& other ) const
{
return static_cast< T const* >( this )->compare( other ) == 0;
}

operator==operator!=只需使用 isEqual , 不涉及模板元编程。如果派生类定义一个 isEqual ,它隐藏了这个,它被使用了。如果不,这个已经习惯了。

关于C++ 关系运算符生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23388739/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com