通过隐式转换小于运算符?
Less than operator through implicit conversion?
考虑以下 class:
struct C
{
/* Class contents, without any arithmetic operator... */
constexpr operator int() noexcept; // Implicit conversion to int
};
我的问题是:
- C 是否可用于
std::sort
目前使用默认 < 运算符的标准算法?
- C是否被认为满足
LessThanComparable
概念?
- C 是否满足假设的概念化算法库的要求,该库要求类型为
LessThanComparable
。
没有。编译器不能做这么大的魔术,即调用 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;
}
}
因为这样会产生歧义。所以,这样做不是一个好主意。
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
概念的要求是,对于 C
或 const C
类型的对象 x
和 y
,表达式 x<y
是有效且隐式的可转换为 bool 和 <
运算符建立严格的弱排序关系。在您的情况下,const 对象不会转换为 int
s。这是您代码中的错误,因为它不是 const 正确的。添加 const
关键字将使其起作用,而 class C
确实是 LessThanComparable
。满足严格的弱排序关系,因为 int
s 满足这个要求。
Will C
meet the requirements of an hypothetical conceptified algorithm
library that would require the type to be LessThanComparable
.
如果你修复了常量,是的,它会的。
一些旁注:
GCC 4.9 编译 x<y
,即使 x
和 y
的类型是 const C
。这似乎是一个编译器错误,因为 GCC 5.2 和 clang 3.6 在这里抛出编译时错误。
将 std::less<C>()
作为额外参数传递给 std::sort()
会产生编译时错误,因为在这种情况下比较函数需要常量对象才能进行比较。但是,传递 std::less<void>()
不会破坏任何内容,因为参数已完美转发。
std::sort()
algorithm不需要完整的LessThanComparable
,而是概念Compare
。此外,迭代器类型必须是 RandomAccessIterator
即 ValueSwappable
并且取消引用的类型必须是 MoveContructable
和 MoveAssignable
。你的第一个问题就是这种情况,即使常量错误没有修复。这就是 std::sort()
和其他标准算法起作用的原因。
考虑以下 class:
struct C
{
/* Class contents, without any arithmetic operator... */
constexpr operator int() noexcept; // Implicit conversion to int
};
我的问题是:
- C 是否可用于
std::sort
目前使用默认 < 运算符的标准算法? - C是否被认为满足
LessThanComparable
概念? - C 是否满足假设的概念化算法库的要求,该库要求类型为
LessThanComparable
。
没有。编译器不能做这么大的魔术,即调用 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;
}
}
因为这样会产生歧义。所以,这样做不是一个好主意。
Is
C
usable in standard algorithms likestd::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 theLessThanComparable
concept?
没有。 LessThanComparable
概念的要求是,对于 C
或 const C
类型的对象 x
和 y
,表达式 x<y
是有效且隐式的可转换为 bool 和 <
运算符建立严格的弱排序关系。在您的情况下,const 对象不会转换为 int
s。这是您代码中的错误,因为它不是 const 正确的。添加 const
关键字将使其起作用,而 class C
确实是 LessThanComparable
。满足严格的弱排序关系,因为 int
s 满足这个要求。
Will
C
meet the requirements of an hypothetical conceptified algorithm library that would require the type to beLessThanComparable
.
如果你修复了常量,是的,它会的。
一些旁注:
GCC 4.9 编译
x<y
,即使x
和y
的类型是const C
。这似乎是一个编译器错误,因为 GCC 5.2 和 clang 3.6 在这里抛出编译时错误。将
std::less<C>()
作为额外参数传递给std::sort()
会产生编译时错误,因为在这种情况下比较函数需要常量对象才能进行比较。但是,传递std::less<void>()
不会破坏任何内容,因为参数已完美转发。std::sort()
algorithm不需要完整的LessThanComparable
,而是概念Compare
。此外,迭代器类型必须是RandomAccessIterator
即ValueSwappable
并且取消引用的类型必须是MoveContructable
和MoveAssignable
。你的第一个问题就是这种情况,即使常量错误没有修复。这就是std::sort()
和其他标准算法起作用的原因。