通过隐式转换小于运算符?

Less than operator through implicit conversion?

考虑以下 class:

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

我的问题是:

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

编辑:实际上这是不正确的。只要有单个 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;
    }
}

Live Demo

因为这样会产生歧义。所以,这样做不是一个好主意。

Is C usable in standard algorithms like std::sort that currently uses the default < operator?

是的,它适用于 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) );
}

编译。 Here's a live demo.不过看下一题!

Is C considered as satisfying the LessThanComparable concept?

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

Will C meet the requirements of an hypothetical conceptified algorithm library that would require the type to be 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() algorithm不需要完整的LessThanComparable,而是概念Compare。此外,迭代器类型必须是 RandomAccessIteratorValueSwappable 并且取消引用的类型必须是 MoveContructableMoveAssignable。你的第一个问题就是这种情况,即使常量错误没有修复。这就是 std::sort() 和其他标准算法起作用的原因。