小于运算符通过隐式转换



考虑以下类:

struct C 
{
     /* Class contents, without any arithmetic operator... */
     constexpr operator int() noexcept; // Implicit conversion to int
};

我的问题是:

  • C 是否可用于当前使用默认 <运算符的标准算法(如std::sort(?>
  • C 是否被认为满足LessThanComparable概念?
  • C 是否满足假设概念化算法库的要求,该算法库需要LessThanComparable类型。

C可用于标准算法,例如当前使用的std::sort 默认<运算符?

是的,它适用于std::sort()和其他一些标准算法。代码

#include <algorithm>
#include <vector>
struct C 
{
     /* Class contents, without any arithmetic operator... */
     constexpr operator int() noexcept {return 0;} // Implicit conversion to int
};
int main()
{
    std::vector<C> v;  
    std::sort( begin(v), end(v) );
}

编译。这是一个现场演示。不过看看下一个问题!

C是否被认为满足LessThanComparable概念?

不。LessThanComparable概念的要求是,对于Cconst C类型的xy的对象,表达式x<y是有效的,并且隐式可转换为布尔值,并且<运算符建立严格的弱排序关系。在您的情况下,const 对象不会转换为 int s。这是代码中的一个错误,因为它不是 const 正确的。添加 const 关键字将使其工作,并且类C确实会LessThanComparable。满足严格的弱排序关系,因为int满足这个要求。

C是否满足假设概念化算法的要求 需要LessThanComparable类型的库。

如果你修复了你的恒常性,是的,它会的。

一些旁注:

  • GCC 4.9 编译x<y即使 xy 属于 const C 类型。这似乎是一个编译器错误,因为GCC 5.2和clang 3.6在这里抛出了一个编译时错误。

  • std::less<C>()作为额外的参数传递给std::sort()会产生编译时错误,因为在这种情况下,比较函数要求常量对象具有可比性。但是,传递std::less<void>()不会破坏任何东西,因为参数是完美转发的。

  • std::sort()算法不需要完全LessThanComparable,但概念Compare。此外,迭代器类型必须是ValueSwappableRandomAccessIterator,并且取消引用的类型必须是MoveContructableMoveAssignable。您的第一个问题就是这种情况,即使恒常性错误未修复。这就是std::sort()和其他标准算法起作用的原因。

No.编译器不能做这么大的魔法,即调用 cast 方法然后应用<运算符。想象一下,不同类型的有几个强制转换运算符,编译器将如何选择合适的转换运算符?

编辑:实际上这是不正确的。只要有单铸运算符,这就可以了。但是对于两个或更多,编译器会抱怨模棱两可的转换。但是,这种方法非常脆弱,因此通常不是好主意。

我尝试了mehrdad momeny提出的例子。它工作正常。但是,只需很少的编辑,它就不再工作了。

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
struct C 
{
    C(int x):X(x){}
    operator int() { return X; }
    operator float() { return static_cast<float>(X); }
    int X;
};
using namespace std;
int main()
{
    vector<C> u = {1, 2, 35, 6, 3, 7, 8, 9, 10};
    sort(u.begin(), u.end());
    for(auto x: u){
        cout << x << endl;
    }
}

现场演示

因为这会导致歧义。因此,这样做不是一个好主意。

相关内容

  • 没有找到相关文章

最新更新