【问题标题】:BOOST_STRONG_TYPEDEF and overloaded relational operatorsBOOST_STRONG_TYPEDEF 和重载的关系运算符
【发布时间】:2015-07-29 16:48:34
【问题描述】:

我正在使用 BOOST_STRONG_TYPEDEF 从 POD 类型中定义强类型。例如,我想从int 定义一个新类型。但是,如果我尝试将我的新类型与不是 int 的东西(例如 unsigned intsize_t)进行比较,我会收到“使用重载运算符 '

例如:

#include <boost/serialization/strong_typedef.hpp>

BOOST_STRONG_TYPEDEF( int, Foo );

int main(int argc, const char * argv[]) {

    Foo f( 10 );

    unsigned int j = 11;
    bool result = j < f;    // Error

    size_t s = 100;
    result = s < f;         // Error

    int h = 101;
    result =  h < f;        // ok

    return 0;
}

我可以通过为特定类型实现特定的关系运算符来修复这些错误。例如:

bool operator<(const size_t& y, const Foo& x) {
    return y < x.t;
}

由于 BOOST_STRONG_TYPEDEF 提供了从 Fooint 的转换运算符,我本来希望 (unsigned int) &lt; (Foo) 编译成与 (unsigned int) &lt; (int) 相同的东西,但我想不会。

我的问题是:有没有办法避免为我想要比较的每种类型实现每个运算符?

【问题讨论】:

    标签: c++ boost types operator-overloading typedef


    【解决方案1】:

    由于 BOOST_STRONG_TYPEDEF 提供了从 Fooint 的转换运算符,我本来希望 (unsigned int) &lt; (Foo) 编译成与 (unsigned int) &lt; (int) 相同的东西,但我想不会。

    BOOST_STRONG_TYPEDEF 宏定义了一个struct Foo,它继承自一堆不同的运算符类,其中一个将定义:

    friend bool operator<(const int&, const Foo&); //(1)
    

    当然还有所有比较整数的内置函数:

    bool operator<(T, U); // (2), implicit
    

    对于所有整数类型,I,我们有几个可行的候选 I{} &lt; Foo{}。我们可以将I 转换为int 并调用(1),或者我们可以将Foo 转换为int 并调用(2)。根据I,结果是:

    • Iint(1) 是完全匹配的,并且所有内置运算符都涉及转换,因此 (1) 无疑是首选。
    • I 的排名低于int(例如char):积分提升(高达int)的排名高于转换(Fooint),所以(1) 无疑是首选。
    • I 的排名高于 int(例如,您的示例中的size_tunsigned int):(1) 现在涉及整数转换(size_tint 不是一个提升),而整数转换有排名转换,排名与用户定义的转换相同。所以(1)(2) 都会有一个完全匹配和一个转换。由于没有一个比另一个更好,所以它是模棱两可的。

    我的问题是:有什么方法可以避免为我想要比较的每种类型实现每个运算符?

    不,没有。但是,您可以使用模板一次性为每种类型实现每个运算符。例如,我们可以解决&lt; 的所有歧义:

    template <typename T>
    bool operator<(const T& t, const Foo& f)
    {
        return t < static_cast<int>(f);
    }
    

    对于等级等于int 的整数类型,(1) 仍然是首选。但是对于所有其他整数类型,模板将是完全匹配的,而内置函数和 (1) 涉及一些转换序列,所以这将是首选 - 这将转发到一个模棱两可的内置函数。

    【讨论】:

    • 非常有用的答案,谢谢。是否有理由更喜欢模板函数中的 static_cast 而不是直接访问 Foo 的 t 成员变量?
    猜你喜欢
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-19
    • 2021-03-05
    相关资源
    最近更新 更多