特定积分常数的重载比较
Overloading comparison for specific integral constants
我正在将一大组地理空间代码从一个投影转换到另一个投影。为了在转换过程中强制使用正确的单位,我引入了"距离"、"点"、"矩形"answers"多边形"模板,这些模板带有一个标记,指示使用的坐标系。这是相当好的,但在很多地方对非零(!= 0
)或正值(> 0
)进行检查。我希望能够重载这些运算符,以便在不与任何其他数字进行比较的情况下与0
进行比较。有可能做到这一点吗?
作为一个额外的限制,我不能使用constexpr
,因为我必须支持VS 2013,但我仍然很想知道是否有办法使用constexpr
仅供参考,我正在使用这样的东西:
template<typename Tag> struct Distance
{
int value;
};
template<typename Tag> struct Point
{
Distance<Tag> x;
Distance<Tag> y;
};
// This works fine for comparing two Distances
template<typename Tag> bool operator>(const Distance<Tag>& a, const Distance<Tag>& b) {return a.value > b.value;}
// But I don't want this to allow a > 14, only a > 0
template<typename Tag> bool operator>(const Distance<Tag>& a, int b) {return a.value > b;}
struct Mercator;
typedef Point<Mercator> MercPoint;
struct GuiScale;
typedef Point<GuiScale> GuiPoint;
// etc.
您可以使用nullptr_t
作为破解(作为文字0
转换为nullptr
):
template<typename Tag> bool operator>(const Distance<Tag>& a, std::nullptr_t b) {return a.value > 0;}
您可以使用对文字零的任何指针的转换:
#include <type_traits>
template<typename Tag>
struct Distance
{
private:
using literal_zero = void(Distance::*)();
template<typename U>
using enable_nullptr = typename std::enable_if<
std::is_same< typename std::decay< U >::type, std::nullptr_t >::value
>::type;
public:
int value;
bool operator<( literal_zero ) const { return value < 0; }
template<typename U>
enable_nullptr<U> operator<( const U& ) const = delete;
};
int main() {
Distance<int> a;
a.value = 0;
a < 0;
// a < 42; // does not compile
// a < nullptr; // does not compile
}
与其他答案不同,这也不允许a < nullptr
。此外,如果删除与nullptr
相关的部分,并用typedef
替换using literal_zero = ...
,那么C++98也可以使用相同的技术。
实时示例
如果与文字0
进行比较在语义上是有效的,那么允许从文字0
进行转换也是有效的。转换到位后,您无需进行特殊情况比较(Coliru Live):
template<typename Tag> struct Distance
{
int value;
Distance() = default;
explicit constexpr Distance(int v) : value(v) {}
constexpr Distance(std::nullptr_t) : value(0) {}
friend constexpr bool operator == (const Distance& lhs, const Distance& rhs) {
return lhs.value == rhs.value;
}
friend constexpr bool operator < (const Distance& lhs, const Distance& rhs) {
return lhs.value < rhs.value;
}
// ...
};
相关文章:
- 不能将重载比较运算符与 Catch 测试一起使用
- 在priority_queue的自定义类中重载比较运算符
- C++ 中的运算符重载(比较运算符)
- 重载比较符号"<"时,C++升序排序的正确方法
- 重载比较运算符 == C++
- 重载比较运算符 C++,如何与 const 参数进行比较
- 重载比较运算符
- 此代码对于重载比较运算符是否正确
- 无法弄清楚为什么使用重载比较运算符在执行前调用复制构造函数
- 堆栈的重载比较运算符
- 特定积分常数的重载比较
- 重载比较运算符以使用C++中的STL排序
- 在C++中使用运算符重载比较哪个字符串更大
- 对double进行重载比较以允许出现数字错误
- 在c++中编写两个基本类型之间的重载比较(==)
- 重载比较运算符的使用>C++与 getter 函数结合使用
- 如何在不重载比较操作符的情况下为std::max专门化自定义类型
- 不能使用操作符重载比较const和非const模板类型
- 如何用矩阵类重载比较运算符
- 重载比较运算符C++会导致"invalid operator<"